等待锁定执行的任务数组

时间:2013-10-20 09:29:50

标签: c# multithreading locking async-await

可以从代码中的多个位置调用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吗?

1 个答案:

答案 0 :(得分:7)

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

    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构造来可靠地释放锁。