C# 使用Factory.StartNew阻止代码执行

C# 使用Factory.StartNew阻止代码执行,c#,C#,当我不使用Thread.Sleep(20)时,Factory.StartNew导致代码执行阻塞 我尝试了以下方法: Thread.Sleep()-这适用于Factory.StartNew&产生理想的结果 任务。延迟(20)-这不适用于Factory.StartNew Task.Run-用它代替Factory.StartNew没有任何区别 守则: private async Task<bool> GetStatus() { var

当我不使用Thread.Sleep(20)时,Factory.StartNew导致代码执行阻塞

我尝试了以下方法:

  • Thread.Sleep()
    -这适用于Factory.StartNew&产生理想的结果

  • 任务。延迟(20)
    -这不适用于Factory.StartNew

  • Task.Run
    -用它代替Factory.StartNew没有任何区别

守则:

private async Task<bool> GetStatus()
{                        
  var MyTask = Task<bool>.Factory.StartNew( () => 
  //var MyTask = Task<bool>.Run( () => // Using Task.Run doesn't make any 
  //difference
  {
    while (true)
    {              
      if (EventStatus.ToString() == "Rejected")
        break;
      if (EventStatus.ToString() == "Error")
        break;
      Thread.Sleep(20);// This gives the desirable result.Removing it 
                       //causes application to hang
      //Task.Delay(20);// This line doesn't make any difference
    }                
    return true;
   });            
  MyTask.Wait();            
  return await MyTask;
}
private异步任务GetStatus()
{                        
var MyTask=Task.Factory.StartNew(()=>
//var MyTask=Task.Run(()=>//使用Task.Run不会产生任何错误
//差别
{
while(true)
{              
if(EventStatus.ToString()=“已拒绝”)
打破
if(EventStatus.ToString()=“Error”)
打破
Thread.Sleep(20);//这会得到理想的结果。删除它
//导致应用程序挂起
//Task.Delay(20);//这行没有任何区别
}                
返回true;
});            
MyTask.Wait();
返回等待我的任务;
}
如果我使用Task.Factory.StartNew而不使用Thread.Sleep(20),代码就会陷入无休止的循环中

如何改进代码并使其在不使用Thread.Sleep(20)的情况下工作


我尝试了Task.Factory.StartNew指定TaskScheduler,但这也导致代码挂起。

首先,不要使用
StartNew
。它是。使用
任务。改为运行

第二,您看到无休止循环的原因是
Task.Delay
只是启动一个计时器,并在计时器启动时返回一个完成的任务。如果您希望代码实际等待计时器,那么您需要
等待该任务。此外,
EventStatus
正在从多个线程访问,而无需保护在上,这不好。您需要添加一个锁来永久修复此问题:

private async Task<bool> GetStatus()
{
  var task = Task.Run(async () =>
  {
    while (true)
    {              
      // TODO: add lock for EventStatus
      if (EventStatus.ToString() == "Rejected")
        break;
      if (EventStatus.ToString() == "Error")
        break;
      await Task.Delay(20);
    }                

    return true;
  });

  return await task;
}
private异步任务GetStatus()
{
var task=task.Run(异步()=>
{
while(true)
{              
//TODO:为EventStatus添加锁
if(EventStatus.ToString()=“已拒绝”)
打破
if(EventStatus.ToString()=“Error”)
打破
等待任务。延迟(20);
}                
返回true;
});
返回等待任务;
}

作为最后一点,我将完全消除这种情况。与其轮询
EventStatus
以进行更改,不如将其设置为实际的“信号”例如,假设
EventStatus
设置了一次,那么
TaskCompletionSource
就可以正常工作。

这可能是因为
Task.Delay
可以等待,而您没有等待它吗?什么是
EventStatus
?它是否使用了正确的锁?否则,C只能读取一次,但不是每次循环迭代都可以读取。EventStatus会在每次callaback事件触发时更新。不,我没有使用任何锁,我将探索此选项。谢谢。