我遗漏了一个重要的概念,我非常感谢您的帮助。我希望我能正确描述我的问题,我是在论坛上发帖并寻求帮助的新手。
我的 Camera 类中有一个异步任务,它将位图从 RTSP 流传输到 UI 中的图片框。 当我启动流任务时,我使用“安全即发即忘”,这样我就可以在 UI 线程上继续。 我不想在我的表单上到处都是等待和异步,它变得难以管理并干扰其他线程。用户界面响应灵敏且运行良好。
现在,当我想要拍摄快照时,我会订阅 Camera 类上的 SnapShotTaken 事件。然后,我调用 Camera 类上的一个函数来告诉它开始拍摄快照(通过设置布尔变量),然后我希望 UI 线程等待在我的表单上触发事件。 我在 UI 上使用带有 Thread.Sleep 的循环,然后锁定 UI 和 Camera 类!
我怎样才能等待回调,并让 Camera 类继续它的工作(我认为它在后台线程上,因为我没有等待它)来向我发出信号,而不会让我阻塞 Camera 类的工作?
这里是从按钮单击事件订阅 Camera 类 (ThisFormIPCamera) 的代码
ThisFormIPCamera.SnaphotTaken += ThisFormIPCamera_RegSnaphotTaken;
ThisFormIPCamera.TakeSnapshot();
这是Camera类中TakeSnapshot的代码,它只是设置一个变量来告诉Camera类 获取收到的下一帧并将其发送回给我。
public void TakeSnapshot()
{
_takeSnapshot = true;
}
UI 上等待的代码显然不好:
int timeoutCounter = 0;
while (!RegPhotoTaken)
{
try
{
System.Threading.Thread.Sleep(200);
}
timeoutCounter++;
if (timeoutCounter > 50)
{
MessageBox.Show("Timeout", GlobalVars.APP_NAME, MessageBoxButtons.OK)
break;
}
}
此代码超时,只有使用 MessageBox 时,Camera 类上的代码才会继续,并且我得到了照片。
我可以使用什么来不允许执行 UI 代码,但允许运行相机类上的任务。
谢谢!
我尝试开始在包含订阅 Camera 类事件的调用的函数上使用 async 和 wait,但整个表单变得非常复杂,而且我的模拟相机出现了问题。 我尝试设置标志来停止其他线程工作,但如果可能的话,我想要一个更干净的解决方案。
您可以使用 TaskCompletionSource 来等待快照,而不是带有睡眠的 while 循环。
我不知道你正在使用的 API,但这可能会提供一个想法:
private TaskCompletionSource<MySnapShot> _tcs = null;
public void Setup()
{
ThisFormIPCamera.SnaphotTaken += ThisFormIPCamera_RegSnaphotTaken;
}
public void ThisFormIPCamera_RegSnaphotTaken(object sender, EventArgs e)
{
if(_tcs == null)
return;
_tcs.SetResult(ThisFormIPCamera.SnapShotImage);
_tcs = null;
}
public async Task<MySnapShot> TakeSnapshot()
{
_tcs = new TaskCompletionSource<MySnapShot>();
ThisFormIPCamera.TakeSnapshot();
return _tcs.Task;
}