代码之家  ›  专栏  ›  技术社区  ›  Dave

关于在C#(WPF)中对COM对象进行异步调用的问题

  •  2
  • Dave  · 技术社区  · 15 年前

    很抱歉问了这么一个基本的问题,但我在这个问题上好像脑子都僵住了!我正在调用WPF项目中的COM(ATL)对象。COM方法可能需要很长时间才能完成。我想我应该试着把它称为非同步的。我有几个演示行显示了这个问题。

    private void checkBox1_Checked(object sender, RoutedEventArgs e)
     {
          //DoSomeWork();
          AsyncDoWork caller = new AsyncDoWork(DoSomeWork);
          IAsyncResult result = caller.BeginInvoke(null, null);            
      }
    
    private delegate void AsyncDoWork();
    private void DoSomeWork()
    {
       _Server.DoWork();
    }
    

    ATL方法非常令人兴奋。它是:

    STDMETHODIMP CSimpleObject::DoWork(void)
    {
       Sleep(5000);
       return S_OK;
    }
    

    我期望以这种方式运行会立即选中复选框(而不是在5秒钟内),并且我能够在屏幕上移动wpfgui。我不能-5秒钟。

    我做错什么了?我相信事情很简单。代表签名错误?

    谢谢。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Ray Burns    15 年前

    两种解决方案:

    1. 将ATL部分重新构建为MTA,这可能不可行,或
    2. 将ATL保留为STA,但首先在为此目的创建的线程中构造COM对象,这样它将获得不同的单元。

    如果您的COM对象本身不是GUI对象,那么在一个单独的工作线程中构造它并将它留在那里应该非常容易。因为它是一个STA对象,所以所有调用都将被封送到另一个线程。

        2
  •  1
  •   JustABill    15 年前

    BeginInvoke Thread

    Thread comthread = new Thread(new ThreadStart(delegate() { DoSomeWork(); }));
    comthread.Start();
    

    或者试试.NET4的新功能 Task library

    Task.Factory.StartNew(() =>
    {
        DoSomeWork();
    });
    

    *委托类型的 异步调用 方法与调用方在同一线程上执行,但在后台执行。我不确定是否有关于什么时候执行的规则,但肯定不是你想要的顺序。但是,异步 方法 喜欢 BeginRead 在独立于主线程的特殊线程上执行。
    线程 对象,而 Task 系统有一个线程池可以使用,这在理论上更有效。

        3
  •  1
  •   Dave    15 年前