簡體   English   中英

異步等待阻塞ui wp8

[英]async await blocking ui wp8

據我所知async await關鍵字以這種方式工作:當編譯器遇到await關鍵字時,它會暫停執行異步函數給調用者(在本例中是調度程序),等待等待函數完成后台然后返回到該函數。 我對嗎?

這就是我在做的事情:

async private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
     var p = await query("select* from notes", con);
}   

這是被調用的函數

 async Task<List<notes>> query(string sqlstring, SQLiteConnection con)
 {
       var p = con.Query<notes>(sqlstring);
       Thread.Sleep(5000);
       MessageBox.Show(p[0].Data); 
       return p;
 }

這會阻止UI線程。 為什么發生這種情況不應該在遇到await關鍵字時將控制權轉移回調度程序? 如果是這樣,為什么用戶界面會被卡住?

您對await理解大多是正確的,它只是不完整。 await不會立即暫停執行當前方法。 首先,需要將值等待解析為值。 通常,您將擁有一種創建Task的方法。 該任務將同步創建 ,然后在創建該任務后,當前方法的執行將結束,並且將繼續執行該任務以執行該方法的其余部分。

對於async方法,第一個await之前的所有內容都將由調用者同步執行。 當第一個await (或方法的結束,或方法未捕獲的異常)導致該方法返回實際的Task

您的query方法應該能夠非常快速地創建表示操作完成的Task ,然后返回,以便調用者可以awaitTask 但事實並非如此,它花費了超過5秒的時間來創建代表何時完成的任務,以及當它最終將任務交給其調用者Task已經完成時。

這意味着在query完成任務創建5秒之后, Button_Tap無法屈服於調用者(這是UI的消息循環)。

所有這一切都意味着對於Button_Tap ,異步query需要是異步的,而不是異步的,因為它使用async關鍵字,但在調用時方法幾乎立即返回,並且在產生控制后執行其工作的意義上是異步的回到來電者。

至於如何使方法異步,這將取決於。 對於IO,例如查詢數據庫,您真正想要的是讓查詢提供程序本身提供固有的異步支持。 您希望有一個返回可以awaitTask的查詢方法,而不是同步返回其結果。 如果您沒有其他選擇,那么作為最后的手段,您可以使用Task.Run在非UI線程中執行查詢,然后await它。

至於Thread.Sleep ,那也是同步阻塞線程。 您需要在一段時間后異步執行某些操作(如果您確實需要延遲)。 您可以使用Task.Delay

async Task<List<notes>> query(string sqlstring, SQLiteConnection con)
{
    var p = await con.QueryAsync<notes>(sqlstring);
    //Or, if there is no asynchronous query method
    //var p = await Task.Run(() => con.Query<notes>(sqlstring));
    await Task.Delay(5000);
    MessageBox.Show(p[0].Data);
    return p;
}

另外,您真的不應該嘗試重復使用這樣的數據庫連接。 對於初學者來說,它們並非旨在同時使用。 實際上它們本身就是為了執行一次操作而設計的。 您應該在需要時立即創建連接,並在執行一個操作后立即清理它。

暫無
暫無

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

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