应用程序之间的对象共享?

2024-02-21

假设我有一个每秒更新 1000 多次的大型数据数组。
另一个应用程序想要在短时间内访问和读取数组。两个应用程序都在同一台机器上。

我曾尝试使用 WCF 进行进程间通信,但每秒序列化和发送整个数组(或大型对象)数千次在性能方面是不可行的。
有没有办法在c#中直接访问来自不同应用程序的对象?


尽管 WCF 之前的版本今天仍然适用,但您可以使用一些 IPC 技术。

Pipes

Pipes就是这样一种技术。它是二进制的,在内核模式下运行并且速度非常快!虽然它的级别相当低并且确实not授予对“对象”的访问权限。

.NET 远程处理

.NET 远程处理将提供对对象的访问,但可能不如管道快。

管道和 .NET 远程处理都比序列化技术 WCF 更快,后者将内容转换为详细的 XML/SOAP。

COM

COM 是 IPC 的二进制协议。 COM 是一种客户端服务器模型,客户端从 COM 或 OLE 服务器请求数据。 COM 的美妙之处在于您拥有直接访问服务器中的对象 - 它们没有被序列化。例如请求 a 中的元素安全阵列 https://msdn.microsoft.com/en-us/library/windows/desktop/ms221482(v=vs.85).aspx.

A SAFEARRAY是由类型安全数据组成的任意维度的自动化安全结构。幸运的是,.NET 将为我们隐藏 SAFEARRAY gobble-de-gook。

在我的示例中,我创建了一个Manager将公开数组的类。为了到达Manager我使用了工厂模式,这样Manager本质上是一个单例。

您应该按如下方式布局您的项目:

  • MyComLib.Contracts.dll- 包含所有接口
  • MyComLib.dll- 包含实施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("...")]
[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("...")]
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
}

一个测试应用程序。这应该only参考MyComLib.Contracts.dll and 不是 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;
    }
}

最后一步是改变这一点进行中COM 服务器到进程外COM 服务器,以便多个进程各自共享相同的内容Manager并且不要创建自己的单例。换句话说,是跨进程的单例。当。。。的时候Manager在运行时,它本质上是在它自己的进程空间中与所有其他客户端进程分开。

为此,您需要配置一个 COM 代理,详细解释如下here http://dotnet.dzone.com/articles/hosting-net-dll-out-process.

文件映射/共享内存

最后,文件映射允许您操作文件,就好像它只不过是进程地址空间中的一大块内存一样。无需繁琐的文件查找;读/写操作。只需获取指向内存块的指针并开始读/写。系统将完成剩下的工作。

MSDN:

您可以使用文件映射的特殊情况在进程之间提供命名共享内存。如果在创建文件映射对象时指定系统交换文件,则文件映射对象将被视为共享内存块。其他进程可以通过打开同一文件映射对象来访问同一内存块。告诉我更多 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx#base.using_a_file_mapping_for_ipc

遗憾的是,它仍然需要您首先写入数据,并且为了使其最有效,您需要更改应用程序以将内存块视为事实来源,而不是内存中的数组。否则你将一直在序列化。

然而,通过交换文件共享内存在技术上确实允许您消除客户端-服务器应用程序之间的任何序列化-反序列化以及“堆上”的数据重复。尽管正如我所说,您可能需要调整您的应用程序以使用原始内存缓冲区而不是对象。

告诉我更多

  • .NET Framework 中的管道操作 https://msdn.microsoft.com/en-us/library/bb762927(v=vs.110).aspx
  • .NET 远程处理 https://msdn.microsoft.com/en-us/library/vstudio/72x4h507(v=vs.100).aspx
  • 进程间通信 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx#base.using_com_for_ipc

NOTE:与普遍看法相反,.NET Remotingis not完全obsolete。它的当代用途之一是不同环境中的对象之间的通信AppDomains在同一流程中,您通常会做的事情plug-in systems.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应用程序之间的对象共享? 的相关文章

随机推荐

  • 如何使项目浮动在 Jquery 对话框之外

    我想要一个看起来像这样的对话框 我认为这种方法可行 但我想我错了 JavaScript Creates The Dialog ImageDialogDiv dialog position 98 223 resizable false mod
  • jQuery 提交验证,最后有模式对话框?

    我现在有一个表格想要验证 假设一切都正确 我希望它弹出一个对话框确认其详细信息 这是我迄今为止的代码示例 var userConfirmed false dialog dialog buttons Yes function userConf
  • 如何理解ndarray.reshape函数?

    原型为reshape 就是它reshape shape order C 形状的类型是元组 所以我们应该用以下方式调用这个函数myarray reshape 1000 1 32 32 但是我发现很多人用myarray reshape 1000
  • 如何使 Apache mod_deflate 和 Transfer-encoding : Chunked 一起工作?

    我正在尝试在我们的网站上使用大管道概念 这意味着尝试以块的形式发送响应 而不是整体发送响应 以便用户感觉该页面很快 我通过在 java 中的响应对象上使用flushBuffer方法成功地做到了这一点 但是现在 当我尝试使用 apache m
  • 浮点到字符串:字符串长度问题

    我想将浮点值转换为字符串并创建以下简短示例 with Ada Text IO procedure Example is A constant Float 1 234 B constant Float 123 456 789 C consta
  • 寻找一种算法以(伪)随机顺序吐出数字序列

    假设我有一个数字序列 n n 1 n 2 n m 在不提前存储数字的情况下 我想创建一个函数 f 给定序列 1 2 3 m 将以随机 或至少伪随机 顺序吐出原始集合 例如 假设我的序列是 10 11 12 13 14 15 16 17 f
  • UWP - 调试器已附加到 .exe 但未配置

    I m developing Windows Store App UWP and I have a problem with native code I have this message 此代码第二次或第三次触发后抛出此异常 if Pro
  • 删除 DCG 中的左递归 - Prolog

    我在这个语法中遇到了一个关于左递归的小问题 我正在尝试用 Prolog 编写它 但我不知道如何删除左递归
  • 添加另一个对象时出现 java.util.ConcurrentModificationException

    我正在遭受这个例外 我的代码有什么问题 我只想将另一个人的重复名字分开ArrayList public class GlennTestMain static ArrayList
  • 保存时,将添加的文本视图位置保留在图像视图上

    有一个主要活动有两个按钮 一个是 添加文本 另一个是 保存图像 这是主要布局的一部分
  • 在 iOS 6 上使用 AFNetworking 下载文件

    我最近更新到 AFNetworking 2 0 文档说兼容iOS6 0 当我尝试实现下载方法 图像和视频 时 我正在构建一个 iOS 6 0 应用程序 示例使用 AFURLSessionManager manager AFURLSessio
  • 始终生成为 h2 DDL 中的身份

    在我们的项目中 我们使用 postgres 数据库作为开发到生产环境 对于 junit 测试 我们在内存数据库中使用 H2 想知道我们是否可以使用 GENERATE ALWAYS AS IDENTITY 创建 DDL 以在 H2 数据库中插
  • nohup 作为后台任务不返回提示

    我试图在后台运行一个长时间运行的任务 而无需登录并让终端返回提示 但是当我这样做时 该任务似乎进入后台 但我的提示不可用 除非我按 Control C 我想运行任务然后得到提示 staging php pos web nohup php t
  • 如何解析 Scala 中的命令行参数? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在 Scala 中解析命令行参数的好方法是什么 Related 如何解析 Java 中的命令行参数 https stackoverflow co
  • android jdbc odbc 连接

    我想将 odbc 连接连接到我的 Android 应用程序 我的数据库是oracle 10g 在我的代码中 我的表名称是 world 编译我的程序并关闭模拟器在 oracle 数据库中打开的表后 无法存储值 我在 cmp 中编译普通 jav
  • 使用 pandas.cut 和 IntervalIndex 后如何重命名类别?

    我使用离散化数据框中的一列pandas cut与创建的垃圾箱IntervalIndex from tuples 剪切按预期工作 但是类别显示为我在IntervalIndex 有什么方法可以将类别重命名为不同的标签 例如 小号中号大号 Exa
  • 如何使用 CSS 定位文本输入字段?

    假设您有以下 HTML
  • 使用JAVA从jar文件中读取MANIFEST.MF文件

    有什么方法可以读取 jar 文件的内容吗 就像我想读取清单文件以便找到 jar 文件的创建者和版本一样 有什么办法可以达到同样的目的 下一个代码应该有帮助 JarInputStream jarStream new JarInputStrea
  • 正则表达式匹配两个不相等的数字

    我想知道如何匹配两个不同的数字 所以 匹配 12 就可以了 但不能匹配 11 到目前为止我所拥有的是 我必须匹配像 P12 这样的字符串 我已经用这个正则表达式完成了 P 1 6 1 1 6 1 但现在我的问题是如何仅匹配 P12 或 P3
  • 应用程序之间的对象共享?

    假设我有一个每秒更新 1000 多次的大型数据数组 另一个应用程序想要在短时间内访问和读取数组 两个应用程序都在同一台机器上 我曾尝试使用 WCF 进行进程间通信 但每秒序列化和发送整个数组 或大型对象 数千次在性能方面是不可行的 有没有办