2

可以从代码中的多个位置调用 TestAwaitTaskArrayAsync()。我需要锁定 taskArray 的执行并异步等待,直到其所有任务完成,然后下一次调用将开始执行 taskArray。这是代码:

private async Task TestAwaitTaskArrayAsync()
        {
            Task[] taskArray;
            lock (_lock_taskArray)
            {
              taskArray = new Task[]
              {
                Task.Run(() =>
                {
                    SomeMethod1();
                }),
                Task.Run(() =>
                {
                    SomeMethod2();
                })
              };
            }
            await Task.WhenAll(taskArray);
        }

不允许锁定等待,因此我可以在必要时使用AsyncLock ,但尽量保持简单。此代码是否正确且线程安全?我不确定是否等待 Task.WhenAll(taskArray); 可以在锁定之外,我应该使用 AsyncLock 代替吗?

4

1 回答 1

7

您使用的锁几乎没有任何效果,因为创建任务非常快并且不会与任何东西冲突。在异步设置中实现互斥的方法是使用SemaphoreSlim类。它是一个支持任务异步模式的锁。

    SemaphoreSlim sem = new SemaphoreSlim(1);
    private async Task TestAwaitTaskArrayAsync()
    {
        await sem.WaitAsync();
        try {
         Task[] taskArray = new Task[]
           {
             Task.Run(() =>
             {
                 SomeMethod1();
             }),
             Task.Run(() =>
             {
                 SomeMethod2();
             })
           };
         }
         await Task.WhenAll(taskArray);
        }
        finally { sem.Release(); }
    }

以同步方式,这会更容易:

lock (_lock_taskArray)
 Parallel.Invoke(() => SomeMethod1(), () => SomeMethod2());

完毕。

AsyncLock如果你喜欢,你也可以使用。这应该允许您使用该using构造可靠地释放锁。

于 2013-10-20T09:54:54.640 回答