웹 카메라에서 이미지를 읽으려고 할 때 최근에이 문제가 발생했습니다. 내가 한 일은 싱글 스레드 메서드가 실행 된 새로운 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();
}
}
의견을 보내 주셔서 감사합니다. 하지만 MTA 스레드에 의해 만들어진 UI 요소를 호출 할 때 동일한 오류가 발생했습니다. – xsl
응용 프로그램 시작 방법을 제어 할 수 있습니까? 컨테이너 앱으로 포장 할 수있는 것보다 큽니다. 스레드를 만들고 COM을 초기화하고 프로그램의 Main 메서드를 호출하십시오. 응용 프로그램에 따라이 프로그램이 작동하거나 작동하지 않을 수 있으며 주 프로그램이 중단 될 수 있지만 최후의 수단이 될 수 있습니다. (주 응용 프로그램을 디 컴파일하고 변경하기 전에 불법 일 수 있습니다.) 또한 개발 한 회사에 문의 할 수도 있습니다. – devdimi
새 스레드 t를 시작하고 t.SetApartmentState (System.Threading.ApartmentState.STA), t.Start()를 사용하면 아무 것도 잘못 될 수 있습니다. 그냥 작동, 내 거대한 애플 리케이션에서 직장에서 테스트. – Harry