为什么要在Task.Run中使用Async?

时间:2019-10-30 20:17:57

标签: c# asynchronous async-await task-parallel-library

在编写某些代码时,我遇到了以下问题,

方法1:

private void MyMethod()
{
    var t = Task.Run(
        async () =>
        {
            Foo.Fim();
            await Task.Delay(5000); 
        });
    t.Wait();
}

我们特意引入5秒的延迟,以允许Fim()完成其工作。必须引入延迟-想象这要调用要求冷却时间为5秒的第三方API。

我想了解这种等待操作完成的正确方法。方法1与以下方法2有何不同?还是有更好的方法来做到这一点?我们需要做的是延迟冷却时间并避免阻塞UI。

方法2:

private void MyMethod()
{
    var t = Task.Run(
        () =>         
        {
            Foo.Fim();
            Task.Delay(5000).Wait(); // some operation which takes 5  seconds.
        });
    t.Wait();
}

1 个答案:

答案 0 :(得分:1)

您需要的是节流阀,用于实现一个的便捷类是SemaphoreSlim

  

限制可以同时访问资源或资源池的线程数。

private SemaphoreSlim _myMethodSemaphore = new SemaphoreSlim(1);

private void MyMethod()
{
    _ = Task.Run(async () =>
    {
        await _myMethodSemaphore.WaitAsync();
        try
        {
            Foo.Fim();
        }
        finally
        {
            await Task.Delay(5000); // Impose the delay even in case of an exception
            _myMethodSemaphore.Release();
        }
    });
}

请注意,此示例中没有Wait()。唯一的阻塞调用是Foo.Fim()方法调用。通过使该方法异步,您可以得到关于可伸缩性的完美解决方案:await Foo.FimAsync()