Этот код блокируется, потому что pictureBox1.Invoke
пытается выполнить код в потоке пользовательского интерфейса.Этот поток заблокирован вызовом threadGrab.Join();
. Это можно исправить с помощью async/await
.await
ожидает выполнения асинхронных задач без блокировки, как Join()
.Когда он заканчивается, выполнение возобновляется в исходном контексте синхронизации.В приложениях WinForms или WPF это означает, что выполнение возобновляется в потоке пользовательского интерфейса.
Полагаю, единственное, что нужно запустить в фоновом режиме, - это m_camera.GrabImage();
.В этом случае код может выглядеть примерно так:
public async void Button1_Click(object sender, EventArgs args)
{
await Task.Run(()=>m_camera.GrabImage();
//Back in the UI thread
SaveImage();
var copyBmp = (Bitmap)mImage.bmp.Clone();
pictureBox1.Image = copyBmp;
m_camera.ReleaseImage();
}
Task.Run
выполнит m_camera.GrabImage()
в потоке потоков.await
будет ожидать завершения этой операции без блокировки потока пользовательского интерфейса.Когда он заканчивается, выполнение возобновляется в потоке пользовательского интерфейса, что означает, что Invoke
.
не требуется. Это также может выполняться в цикле:
public async void Capture_Click(object sender, EventArgs args)
{
while(someCondition)
{
await Task.Run(()=>m_camera.GrabImage();
SaveImage();
var copyBmp = (Bitmap)mImage.bmp.Clone();
pictureBox1.Image = copyBmp;
m_camera.ReleaseImage();
}
}