簡體   English   中英

Task.Await循環內的行為不符合預期

[英]Task.Await within loop not acting as intended

我有一個等待異步線程返回的類。 我要做的是啟動一個while循環,並每秒檢查一次它的位置。

public class AsychronousThingy
{
   public bool IsComplete{get;private set;}
   public string Result {get;private set;}
   public void StartDoingThings(){
       IsComplete = false;
       // kick of an asynchronous thread to do stuff...
   }
   private void OnComplete(){
       IsComplete = true;
       Result = "magical result";
   }
}
public class ActionExecutor{
    public async Task<CustomThingyTaskResult> DoStuff(){
        var thing = new AsychronousThingy();
        thing.StartDoingThings();

        // this returns instantly...?
        while(!thing.IsComplete){
             await Task.Delay(1000);
        }

        // do stuff once the 'thing' is complete.
        return new CustomThingyTaskResult(thing.Result);
    }
}
class Program{
    public static void Main(){
         var exec = new ActionExecutor();
         var returnValue = await exec.DoStuff();
    }
}

我不確定為什么會立即返回。 這是一個問題-您不能在循環內使用Task.Delay嗎? 奇。

我確信這會在完成之前返回,因為當我從異步類的OnComplete事件中進行console.writeline ,它實際上是我的主方法完成之后完成的。

因為DoStuff()是異步的,所以它在被調用時異步完成。 這解釋了為什么異步操作完成后main方法已經返回。 但是,由於DoStuff返回void ,因此您無法像通常那樣await它。 您可以將返回類型更改為Task ,然后await它。

等待循環沒有什么錯,除了使用事件(或其他同步機制)更有效。 同樣, AsynchronousThingy也可能根據Task來表達:-)

您的Main()函數為void 結果,在第一次擊中實際的async操作(在您的示例中為await Task.Delay(1000) )之后,它將控制權返回給其調用方。 因此,您可以如下更改Main()函數的簽名:

public static async Task Main() {...}

然后等待。

或者,您也可以不使用async關鍵字,而使用舊的Wait / Result:

public static void Main()
{
...
var returnValue = exec.DoStuff().Result;
// Or, if there is a SynchronizationContext
returnValue = Task.Run(() => exec.DoStuff()).Result; // This may prevent dead locks that can occur in previous line
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM