【问题标题】:C# COM Cross ThreadC# COM 跨线程
【发布时间】:2011-03-02 17:46:16
【问题描述】:

我们正在开发一种软​​件来控制科学测量设备。它提供了一个 COM 接口,定义了几个函数来设置测量参数并在测量数据时触发一个事件。

为了测试我们的软件,我正在实现该设备的模拟。

com-object 运行一个循环,周期性地触发事件。客户端应用程序中的另一个循环现在应该使用给定的函数设置 com 模拟器。

我创建了一个用于测量参数的类,该类将在设置新测量时实例化。

// COM-Object
public class MeasurementParams
{
    public double Param1;
    public double Param2;
}

public class COM_Sim : ICOMDevice
{
    public MeasurementParams newMeasurement;
    IClient client;

    public int NewMeasurement()
    {
        newMeasurment = new MeasurementParam();
    }

    public int SetParam1(double val)
    {
        // why is newMeasurement null when method is called from client loop
        newMeasurement.Param1 = val;
    }

    void loop()
    {
        while(true)
        {
            // fire event
            client.HandleEvent;
        }
    }
}

public class Client : IClient
{
    ICOMDevice server;

    public int HandleEvent()
    {
        // handle this event
        server.NewMeasurement();
        server.SetParam1(0.0);
    }

    void loop()
    {
        while(true)
        {
            // do some stuff...
            server.NewMeasurement();
            server.SetParam1(0.0);
        }
    }
}

两个循环都在独立的线程中运行。当调用 server.NewMeasurement() 时,服务器上的对象被设置为一个新实例。但在下一个函数中,该对象再次为空。在处理服务器事件时做同样的事情,它工作得很好,因为该方法在服务器线程中运行。如何使它也可以从客户端线程工作。

由于客户端是要使用真实设备的,我无法修改制造商提供的接口。我还需要设置独立于事件处理程序的测量值,它不会定期触发。

我认为这个问题与多线程 COM 行为有关,但我没有找到关于这个主题的任何内容。

【问题讨论】:

    标签: c# multithreading com


    【解决方案1】:

    什么是客户端和服务器的线程模型 - STA 或 MTA? (供参考 - STA 是单线程 Com 对象,旨在一次仅允许从一个线程访问其公共方法,而 MTA 是多线程对象,允许从多个线程同时访问其公共方法)

    每个实例有多少个实例,如何创建这些实例?我怀疑你只想要一个,但你最终会得到多个。

    你有多少个线程,哪个方法在哪个线程上运行?您如何创建这些线程以及它们是否被初始化为运行 STA 对象或 MTA?

    注意: .NET 足够智能,可以检测客户端和服务器是否都受到管理,并将 COM 排除在外。因此,您的模拟运行的是纯托管代码。如果您想要正确的测试客户端,则需要将其编写为 C++(因为我怀疑您的设备控制器是非托管代码)。

    关于 COM 线程模型的参考文档:

    Understanding and Using COM Threading Models
    Processes, Threads and Appartments
    Introduction to COM Interop

    【讨论】:

      【解决方案2】:

      在您发布的代码中,从未分配过COM_Sim.client。有什么遗漏吗?如果不查看对象是如何分配的,就很难诊断。

      另外:您目前在 COM_Sim 中将 newMeasurement 声明为公共字段,但在方法中将 newMeasurment(拼写不同)。如所写,此代码不会编译。您的实际方法中可能存在类似的错字,导致您分配给与您认为在 NewMeasurement 中创建的对象不同的对象。

      【讨论】:

        猜你喜欢
        • 2014-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-25
        • 2017-09-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多