C# Win Forms:使用 Thread.Sleep 在 UI 上循环等待不允许异步任务(未等待)执行其代码

问题描述 投票:0回答:1

我遗漏了一个重要的概念,我非常感谢您的帮助。我希望我能正确描述我的问题,我是在论坛上发帖并寻求帮助的新手。

我的 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,但整个表单变得非常复杂,而且我的模拟相机出现了问题。 我尝试设置标志来停止其他线程工作,但如果可能的话,我想要一个更干净的解决方案。

c# multithreading asynchronous task ui-thread
1个回答
0
投票

您可以使用 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.