一个例子:
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个任务,对吗?这看起来真的很低。 它是每个进程,每个线程,每个会话,......?
感谢您的帮助:)
答案 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
。