문제

플러그인으로 .NET 응용 프로그램을 다른 .NET 응용 프로그램에 포함시켜야합니다. 플러그인 인터페이스는 템플릿 양식에서 상속해야합니다. 그런 다음 플러그인이로드되면 양식이 MDI에 부착됩니다.

지금까지 모든 것이 작동하지만 드래그 앤 드롭 이벤트에 등록 할 때마다 콤보 박스 또는 기타 여러 상황에서 다음과 같은 예외를 설정합니다.

... OLE 호출이 이루어지기 전에 현재 스레드는 단일 스레드 아파트 (STA) 모드로 설정해야합니다. 주요 기능에 stathreadattribute에 표시되어 있는지 확인하십시오 ...

주요 응용 프로그램은 MTA에서 실행되고 있으며 다른 회사가 개발하므로 할 수있는 일은 없습니다.

STA 스레드에서 이러한 예외를 일으키는 일을하려고했지만 문제를 해결하지 못했습니다.

같은 상황에 처한 사람이 있습니까? 문제를 해결하기 위해 할 수있는 일이 있습니까?

도움이 되었습니까?

해결책 3

업데이트 : 회사는 새로운 STA 버전을 출시했습니다. 질문은 더 이상 관련이 없습니다.

다른 팁

새 스레드를 생성하고 0으로 0으로 Coinitialize를 호출 하고이 스레드에서 응용 프로그램을 실행할 수 있습니다. 그러나이 스레드 내에서 직접 컨트롤을 업데이트하지 않으면 모든 UI 수정에 대해 컨트롤을 사용해야합니다.

이것이 확실히 작동하는지 모르겠지만 시도해 볼 수 있습니다.

나는 최근에 웹 카메라에서 이미지를 읽으려고 노력 하면서이 문제를 직접 수행했습니다. 내가 한 일은 단일 스레드 방법이 실행 된 새로운 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();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top