This question already has answers here:
Calling TaskCompletionSource.SetResult in a non blocking manner
(4个答案)
3年前关闭。
我面临着一段我的代码中的僵局问题。值得庆幸的是,我已经能够在下面的示例中重现该问题。作为普通的.Net Core 2.0控制台应用程序运行。
我期望的是完整的序列,如下所示:
但是,实际序列会停在
最后,如果我在
为什么(在哪里)发生僵局?
注意:在原始代码中,我使用 调用 调用
(4个答案)
3年前关闭。
我面临着一段我的代码中的僵局问题。值得庆幸的是,我已经能够在下面的示例中重现该问题。作为普通的.Net Core 2.0控制台应用程序运行。
class Class2
{
static void Main(string[] args)
{
Task.Run(MainAsync);
Console.WriteLine("Press any key...");
Console.ReadKey();
}
static async Task MainAsync()
{
await StartAsync();
//await Task.Delay(1); //a little delay makes it working
Stop();
}
static async Task StartAsync()
{
var tcs = new TaskCompletionSource<object>();
StartCore(tcs);
await tcs.Task;
}
static void StartCore(TaskCompletionSource<object> tcs)
{
_cts = new CancellationTokenSource();
_thread = new Thread(Worker);
_thread.Start(tcs);
}
static Thread _thread;
static CancellationTokenSource _cts;
static void Worker(object state)
{
Console.WriteLine("entering worker");
Thread.Sleep(100); //some work
var tcs = (TaskCompletionSource<object>)state;
tcs.SetResult(null);
Console.WriteLine("entering loop");
while (_cts.IsCancellationRequested == false)
{
Thread.Sleep(100); //some work
}
Console.WriteLine("exiting worker");
}
static void Stop()
{
Console.WriteLine("entering stop");
_cts.Cancel();
_thread.Join();
Console.WriteLine("exiting stop");
}
}
我期望的是完整的序列,如下所示:
Press any key...
entering worker
entering loop
entering stop
exiting worker
exiting stop
但是,实际序列会停在
Thread.Join
调用上:Press any key...
entering worker
entering stop
最后,如果我在
MainAsync
主体中插入一个小的延迟,一切都会很好。为什么(在哪里)发生僵局?
注意:在原始代码中,我使用
SemaphoreSlim
而不是TaskCompletionSource
解决了,根本没有问题。我只想了解问题出在哪里。 最佳答案
直到基本任务完成后,才会返回tcs.SetResult(null);
中的Worker()
调用(有关详细信息,请检查this question)。在这种情况下,任务状态为WaitingForActivation
,这就是为什么会出现死锁的原因:
Worker()
会阻止执行tcs.SetResult(null)
的线程。 Stop()
阻止执行_thread.Join()
的线程。 关于c# - 是什么导致僵局?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47901988/
10-09 02:01