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

.NET - What could happen if we lock(TaskInstance) not shared?

一个例子:

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 lock myTask 时,就像是在做lock(this),对吧?

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

3) 如果这个实例只在这段代码的控制范围内使用,是否有可能myContinuedTask永远不会得到锁,从而一直处于等待状态? 我知道任务由 TaskScheduler 管理。而且我不知道这个是否正在锁定可能导致死锁的任务实例? (我需要更多信息)

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

感谢您的帮助:)

1) When myContinuedTask lock myTask, it's like making lock(this), right ?

否;与 lock(myContinuedTask).

相同

2) This is not a good idea if the instance is used outside the control of this code, right ?

正确。您希望尽可能始终锁定私有或局部范围变量。另外,我建议有一个单独的object,它只用作锁,没有别的。

3) If this instance is only used inside the control of this code, is it possible that myContinuedTask will Never get the lock and, thus, will stay in a waiting state ? I know that tasks are managed by a TaskScheduler. And I don't know if this one is making some lock on the task instances which could possibly lead to a dead lock ?? (i need more info)

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

4) The Id field of a Task is not guarented to be unique. It's an int, so 4^32 max tasks can exists, right ? This seems really low. Is it per process, per thread, per session, ... ?

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


代码的其他问题包括:

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

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