繁体   English   中英

异步/等待信号量仅限制最新任务

[英]Async/Await SemaphoreSlim only newest task

我使用轨迹栏作为形态图像操作的输入值控件。 此操作需要一段时间,因此我想使用async / await来保持轨迹栏滚动的平滑移动。

我做了什么:

private static SemaphoreSlim Sema = new SemaphoreSlim(1,1);
private async void Operation()
{
    if(pictureBox_Image.Image != null)
    {
        await Sema.WaitAsync();
        try
        {
            await Task.Run(() => DoStuff());
        }
        catch{}
        finally
        {
            Sema.Release();
        }
    }
 }

但是通过这种方式,它仍然可以计算所有跟踪栏值的结果。

如何删除所有等待的任务,因此在完成一个值的计算后,只有最新的任务/跟踪栏值才可用于下一次计算?

例子:

跟踪栏值[0,1,2,3,4,5,6]计算从0开始->完成并显示结果->跟踪栏值现在为4->仅使用1,2,3->不计算与4。

因此,还要为您的方法提供一个CancellationToken,并在取消该方法时采取相应的措施。 目前尚不清楚如何调用此方法,因此通常需要保留在调用站点提供令牌的最新CancellationTokenSource。 在下一次调用Operation之前,应将其取消。

private static SemaphoreSlim Sema = new SemaphoreSlim(1,1);
private async void Operation(CancellationToken ct = default)
{
    if(pictureBox_Image.Image != null)
    {
        await Sema.WaitAsync(ct); //throws if cancelled... will not proceed
        try
        {
            await Task.Run(() => DoStuff(ct)); //DoStuff should be checking this CT too
        }
        catch{}
        finally
        {
            Sema.Release();
        }
    }
 }

...在事件处理程序中使用:

currentCancellationTokenSource.Cancel(); //class property/field
currentCancellationTokenSource.Dispose();
currentCancellationTokenSource = new CancellationTokenSource();
Operation(currentCancellationTokenSource.Token);

这可能会导致在需要处理的地方导致OperationCanceledException。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM