0

一个例子 :

try
{
    var myTask = Task.Run(async () =>
    {
        await Task.Delay(1);
    });

    myTask.ContinueWith(myContinuedTask =>
    {
        lock (myTask)
        {
            Task.Delay(1).Wait();
            Console.WriteLine(myContinuedTask.Id);
        }
    });
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

1)当myContinuedTask 锁定myTask 时,就像锁定(this)一样,对吧?

2) 如果实例在此代码的控制之外使用,这不是一个好主意,对吧?

3)如果此实例仅在此代码的控制范围内使用,myContinuedTask 是否有可能永远不会获得锁,因此会保持等待状态?我知道任务是由 TaskScheduler 管理的。而且我不知道这是否对可能导致死锁的任务实例进行了锁定?(我需要更多信息)

4)任务的Id字段不保证是唯一的。它是一个整数,所以最多可以存在 4^32 个任务,对吧?这似乎真的很低。它是每个进程,每个线程,每个会话,...?

感谢您的帮助 :)

4

1 回答 1

0

1)当myContinuedTask 锁定myTask 时,就像锁定(this)一样,对吧?

不; 它与 相同lock(myContinuedTask)

2) 如果实例在此代码的控制之外使用,这不是一个好主意,对吧?

正确的。您希望尽可能始终锁定私有或本地范围变量。此外,我建议使用一个单独object的仅用作锁而没有其他用途的东西。

3)如果此实例仅在此代码的控制范围内使用,myContinuedTask 是否有可能永远不会获得锁,因此会保持等待状态?我知道任务是由 TaskScheduler 管理的。而且我不知道这是否对可能导致死锁的任务实例进行了锁定?(我需要更多信息)

当然,这是可能的。一旦暴露了用于锁定的对象实例,就会遇到死锁的可能性。

4)任务的Id字段不保证是唯一的。它是一个整数,所以最多可以存在 4^32 个任务,对吧?这似乎真的很低。它是每个进程,每个线程,每个会话,...?

他们只是开始复制,仅此而已。不用担心。


代码的其他问题包括:

  • 使用ContinueWith而不是await.
  • 使用Task.Delay(..).Wait()而不是Thread.Sleep.

此外,由于这是异步代码,您可能需要考虑使用SemaphoreSlim而不是lock.

于 2016-05-02T01:25:38.177 回答