对象应用程序之间共享? [英] Object Sharing between Applications?

查看:145
本文介绍了对象应用程序之间共享?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个大的数据阵列每秒更新1000+次。结果
另一个应用程序要访问和读取在很短的时间间隔的阵列。这两个应用程序在同一台机器上。

Let's say I have a large data array updated 1000+ times per second.
Another application wants to access and read the array in a short interval. Both applications are on the same machine.

我已经使用WCF的进程间通信,但每秒钟序列化和发送整个数组(或大对象)数以千计的尝试是不可行的性能明智的。结果
是有直接访问在C#中来自不同应用对象的方法吗?

I have tried using WCF for interprocess communication, but serializing and sending the whole array (or a large object) thousands of times per second is unfeasible performance wise.
Is there a way to directly access objects from different applications in c#?

推荐答案

有,你可以使用一些工控机技术,虽然日期前WCF仍然适用于今天。

There are a few IPC technologies you can use that though pre-date WCF are still relevant today.

管道的就是这样一种技术。这是二进制的,运行在内核模式和速度非常快!虽然这是相当级别低,确实的不可以给获得对象。

Pipes is one such technology. It's binary, runs in Kernel mode and very fast! Though it's quite low-level and does not give access to "objects".

.NET远程的就可以访问对象,但也许没有那么快如管道。

.NET Remoting will give access to objects but is perhaps not as fast as pipes.

两个管道和.NET远程比系列化的技术WCF它转换的东西冗长的XML / SOAP更快。

Both pipes and .NET remoting are faster than serialization-technologies WCF which converts things to verbose XML/SOAP.

COM是二进制协议IPC。 COM是一种客户端 - 服务器模型,其中客户端从COM或OLE服务器请求数据。有关COM的好处是,你有直接进入,即可在服务器对象 - 它们不是序列化。例如,要求在 SAFEARRAY 的元素。

COM is a binary protocol for IPC. COM is a client server model where the client requests data from the COM or OLE server. The beauty about COM is that you have direct access to objects in the server - they are not serialised. For example requesting an element in a SAFEARRAY.

A SAFEARRAY 是由类型安全的数据任意尺寸的自动化安全结构。幸运的是,.NET将隐藏SAFEARRAY吞噬-DE-对韩国人给我们。

A SAFEARRAY is an Automation-safe structure of arbitrary dimensions consisting of type-safe data. Luckily .NET will hide the SAFEARRAY gobble-de-gook for us.

在我的例子中,我创建了一个管理​​类,将暴露的数组。要到管理​​我已经使用了工厂模式,使管理​​本质上是一个单例。

In my example I have created a Manager class that will expose the array. To get to the Manager I've used a factory pattern so that Manager is essentially a singleton.

您应该制定出您的项目如下:

You should lay out your project as follows:


  • MyComLib .Contracts.dll - 包含了所有的接口

  • MyComLib.dll - 包含厂实施管理​​

  • MyComLib.Contracts.dll - contains all the interfaces
  • MyComLib.dll - contains the implementation of Factory, Manager

首先,合同:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IArrayItem
{
    #region Properties

    string Name { get; set; }

    int Whatsit { get; set; }

    #endregion
}

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IFactory 
{
    #region Methods

    IManager CreateManager();

    #endregion
}

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IManager
{
    #region Properties

    IArrayItem[] Array { get; }

    #endregion
}

public static class MyComLibConstants
{
    public const string FactoryProgId = "MickyD.MyComLib.Factory.1";

}

现在的工厂模式:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof (IFactory))]
[Guid("665B8F60-F39B-4E3D-ACB6-B0739FF2CF13")]
[ProgId(MyComLibConstants.FactoryProgId)]
public class Factory : MarshalByRefObject, IFactory
{
    #region IFactory Members

    /// <summary>
    /// Creates the manager.
    /// </summary>
    /// <returns></returns>
    public IManager CreateManager()
    {
        return Manager.Instance;
    }


    #endregion
}

经理:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof (IManager))]
[Guid("DAF2A948-C550-4360-8C99-EE354D593316")]
internal sealed class Manager : MarshalByRefObject, IManager
{
    private static Manager _instance;

    #region Constructor

    /// <summary>
    /// Prevents a default instance of the <see cref="Manager"/> class from being created.
    /// </summary>
    private Manager()
    {
        const int n = 5000;
        Array = new IArrayItem[n];
        for (int i = 0; i < n; i++)
        {
            Array[i]=new ArrayItem();
        }
    }

    #endregion

    #region Properties


    /// <summary>
    /// Gets the instance.
    /// </summary>
    /// <value>
    /// The instance.
    /// </value>
    public static IManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new Manager();
            }
            return _instance;
        }
    }

    #endregion

    #region IManager Members

    /// <summary>
    /// Gets the array.
    /// </summary>
    /// <value>
    /// The array.
    /// </value>
    public IArrayItem[] Array { get; private set; }

    #endregion
}

一个测试应用程序。这应该的引用 MyComLib.Contracts.dll 不会MyComLib.dll

A test app. This should only reference the MyComLib.Contracts.dll and not MyComLib.dll.

class Program
{
    static void Main(string[] args)
    {
        var type = Type.GetTypeFromProgID(MyComLibConstants.FactoryProgId);
        var factory = Activator.CreateInstance(type) as IFactory;
        var manager = factory.CreateManager();
        var x = manager.Array[500].Whasit;
    }
}



最后一步就是要改变这种的在-Process 的COM服务器到的外的过程的COM服务器,以便多个进程的每个共享相同的管理​​和不创建自己的单身。在otherwords,一个单身跨越的进程。当管理​​运行,它本质上是在它自己的进程空间与所有其他客户端进程中分离出来。

One final step is to change this in-process COM server to an out-of-process COM server so that multiple processes each share the same Manager and don't create their own singletons. In otherwords, a singleton that spans processes. When the Manager is running, it is essentially in it's own process space separate from all the other client processes.

对于您需要配置里面有详细这里讲解了COM的替代。

For that you'll need to configure a COM surrogate which is explained in detail here.

最后,文件映射允许您处理一个文件,就好像它是什么以上的内存中的进程的地址空间大块。没有繁琐的文件求;读/写操作。只要抓住一个指向内存块,并开始读/写。该系统将完成剩下的。

Lastly, File Mapping allows you to manipulate a file as if it were nothing more than a large block of memory in the process's address space. No fiddly file seek; read/write operations. Just grab a pointer to the memory block and start reading/writing. The system will do the rest.

MSDN:

您可以使用文件映射的特殊情况下提供一个名为进程之间共享内存。如果指定了系统中创建一个文件映射对象时交换的文件,该文件映射对象视为一个共享内存块。其他进程可以打开同一个文件映射对象访问相同的内存块。 告诉我详情

You can use a special case of file mapping to provide named shared memory between processes. If you specify the system swapping file when creating a file-mapping object, the file-mapping object is treated as a shared memory block. Other processes can access the same block of memory by opening the same file-mapping object. Tell me more

不幸的是,它仍然没有需要你在第一个地方写你的数据并为它是最有效的,你需要改变你的应用程序治疗内存块作为真理的来源,而不是你的存储阵列。否则,你会被序列化的所有时间。

Sadly, it still does require you to write your data in the first place and for it to be most effective you would need to change your application to treat the memory block as the source of truth rather than your array in memory. Otherwise you'll be serializing all the time.

然而,通过交换文件共享内存并在技术上让你消除你的客户端 - 服务器之间的序列化,反序列化应用程序和堆的数据的复制。但正如我所说的,你可能需要调整您的应用程序与原始内存缓冲区,而不是对象的工作。

However, shared memory via the swap file does technically allow you to eliminate any serialize-de-serialize between your client-server apps and duplication of data "on the heap". Though as I said you may need to adjust your app to work with raw memory buffers rather than objects.

  • Pipe Operations in the .NET Framework
  • .NET Remoting
  • Interprocess Communications

注意:相反,普遍认为,.NET远程的不是完全的过时的。它的一个contemory用途是插件系统中相同的过程中在不同的的AppDomain 对象之间的通信,通常做一些

NOTE: Contrary to popular belief, .NET Remoting is not entirely obsolete. One contemory use for it is communication between objects in different AppDomains within the same process, something you typically do in plug-in systems.

这篇关于对象应用程序之间共享?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆