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

Why to use Async inside Task.Run?

在编写一些代码时,我遇到了以下情况,

方法一:

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

我们特意引入了 5 秒的延迟,以允许 Fim() 完成其工作。需要引入延迟 - 假设这是调用第三方 API,它要求 5 秒的冷却时间。

我想了解这是否是等待操作完成的正确方法。方法 1 与以下方法 2 有何不同?或者有更好的方法吗?我们只需要延迟冷却时间并避免阻塞 UI.

方法二:

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

你需要的是一个节流器,一个方便的 class 来实现一个是 SemaphoreSlim:

Limits the number of threads that can access a resource or pool of resources concurrently.

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()