.NET - 如果我们锁定(TaskInstance)没有共享会发生什么?

时间:2016-05-01 20:56:47

标签: locking task taskscheduler

一个例子:

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时,它就像锁定(这个),对吗?

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

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

4)任务的Id字段不具有独特性。它是一个int,所以最多可以存在4 ^ 32个任务,对吗?这看起来真的很低。 它是每个进程,每个线程,每个会话,......?

感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

  

1)当myContinuedTask锁定myTask时,它就像锁定(这个),对吧?

没有;它与lock(myContinuedTask)相同。

  

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

正确。您希望始终尽可能锁定私有或本地范围变量。另外,我建议使用一个单独的object,它仅用作锁定而不是其他任何内容。

  

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

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

  

4)任务的Id字段不具有独特性。它是一个int,所以最多可以存在4 ^ 32个任务,对吧?这看起来真的很低。它是每个进程,每个线程,每个会话,......?

他们只是开始重复,这就是全部。不用担心。

代码的其他问题包括:

  • 使用ContinueWith代替await
  • 使用Task.Delay(..).Wait()代替Thread.Sleep

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