2009-06-30 89 views
1

我必须将.NET应用程序作为插件包含到另一个.NET应用程序中。插件接口要求我从模板表单继承。当插件被加载时,表单随后会附加到MDI中。STA,MTA和OLE噩梦

一切工作,到目前为止,但每当我注册拖放事件,设置自动完成模式的组合框或在我得到下面的异常其他各种情况:

...当前线程必须设置为 单线程公寓(STA)模式 才能进行OLE呼叫。确保 你的主要功能有 请将STAThreadAttribute上标注...

主要应用在MTA运行,由另一家公司开发的,所以没有什么我可以做些什么。

我试图做的事情,导致STA线程中的这些异常,但也没有解决问题。

有没有人处于相同的情况?我能做些什么来解决这个问题吗?

回答

0

更新:公司发布了一个新的STA版本。这个问题不再相关。

2

你可以尝试产生新的线程,并调用CoInitialize和0(aparment线程)并在这个线程中运行你的应用程序。 但是,您不会直接在此线程内更新控件,您应该使用Control.Invoke进行每个UI修改。

我不知道这是否能够正常工作,但您可以尝试。

+0

谢谢您的建议。我尝试过,但是当我调用由MTA线程创建的UI元素时,我得到了同样的错误。 – xsl 2009-06-30 12:24:51

1

我最近在尝试从网络摄像头读取图像时自己遇到了这个问题。我最终做的是创建一个方法,该方法产生了一个新的STA线程,在该线程上运行单线程方法。

问题

private void TimerTick(object sender, EventArgs e) 
{ 
    // pause timer 
    this.timer.Stop(); 

     try 
     { 
      // get next frame 
      UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0); 

      // copy frame to clipboard 
      UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0); 

      // notify event subscribers 
      if (this.ImageChanged != null) 
      { 
       IDataObject imageData = Clipboard.GetDataObject(); 

       Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap); 

       this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero))); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error capturing the video\r\n\n" + ex.Message); 
      this.Stop(); 
     } 
    } 
    // restart timer 
    Application.DoEvents(); 

    if (!this.isStopped) 
    { 
     this.timer.Start(); 
    } 
} 

的溶液:将单线程逻辑以它自己的方法,并调用从一个新的STA线程此方法。

private void TimerTick(object sender, EventArgs e) 
{ 
    // pause timer 
    this.timer.Stop(); 

    // start a new thread because GetVideoCapture needs to be run in single thread mode 
    Thread newThread = new Thread(new ThreadStart(this.GetVideoCapture)); 
    newThread.SetApartmentState(ApartmentState.STA); 
    newThread.Start(); 

    // restart timer 
    Application.DoEvents(); 

    if (!this.isStopped) 
    { 
     this.timer.Start(); 
    } 
} 

/// <summary> 
/// Captures the next frame from the video feed. 
/// This method needs to be run in single thread mode, because the use of the Clipboard (OLE) requires the STAThread attribute. 
/// </summary> 
private void GetVideoCapture() 
{ 
    try 
    { 
     // get next frame 
     UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0); 

     // copy frame to clipboard 
     UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0); 

     // notify subscribers 
     if (this.ImageChanged!= null) 
     { 
      IDataObject imageData = Clipboard.GetDataObject(); 

      Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap); 

      // raise the event 
      this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero))); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Error capturing video.\r\n\n" + ex.Message); 
     this.Stop(); 
    } 
}