簡體   English   中英

異步/等待+ FromEvent方法

[英]Async/Await + FromEvent method

基於以下問題: 通用FromEvent方法

我怎么知道事件將在應用程序中返回哪個線程? 我可以以某種方式指定它將繼續哪個線程? 使用此功能的線程會怎樣?

當我使用WPF(Dispatcher / Main / UI Thread)時,這些響應似乎很明顯,但是如果我正在使用MTA,STA,Reactive,ThreadPool(Task / BackgroundWorker)線程,該如何預測會發生什么?

除了使用task.Wait()(如果我不必擔心鎖定線程),還有什么真正的好處?

如果您await Task ,那么將捕獲一個“上下文”並將其用於恢復async方法。 除非為null ,否則此“上下文”是當前的SynchronizationContext ,在這種情況下,它是當前的TaskScheduler (這些天通常是線程池調度程序)。

如果要進行async編程,則應使用await而不是Wait 正如我在博客中所解釋的, Wait會導致死鎖

您可能還會發現我的async / await介紹很有幫助。

我怎么知道事件將在應用程序中返回哪個線程?

你不知道 除非特定事件的文檔指定將通過UI線程,線程池線程等執行該事件,否則您永遠不會使用事件。

我可以以某種方式指定它將繼續哪個線程?

如果要在UI線程中運行代碼,請在事件處理程序中封送至UI線程。 如果要在線程池線程中運行代碼,則將新任務添加到處理程序內部的線程池中。 如果不需要,這兩個任務都會增加開銷,因此通常最好查看事件的文檔以了解需要哪個。

但是,對於鏈接的問題,整個想法是,您不再處理事件和事件處理程序,而是處理Task 因此,如果您向任務添加延續,那么問題是該延續將在哪里運行? 這完全由您指定。 您可以使用默認任務計划程序並使其在線程池中運行,您可以傳遞UI SynchronizationContext以在UI線程中運行,也可以只讓它在繼續執行任務的任何地方運行。 (這意味着您不知道將在哪個線程上運行它。)

如果您將任務與await ,則它將自動配置繼續,以在您開始該異步操作(可能是UI線程,也可能不是UI線程)之前在同步上下文中運行。 如果您具體不想這樣做 ,請使用.ConfigureAwait(false);

除了使用task.Wait()(如果我不必擔心鎖定線程),還有什么真正的好處?

使用基於異步任務的方法的原因是您沒有阻塞線程,特別是線程池線程(因為您專門說過沒有阻塞UI,這更糟)。 在某些環境中,讓線程無所事事是一個問題,這在某些環境中要比在其他環境中要多得多(例如,用於高度活躍站點的ASP)。 通過不執行阻塞等待,您不會消耗這些資源。

使用鏈接到的技術,您無法預測運行該線程的線程。 可能是引發事件的線程,但是不能保證(不,真的!不是。這是常見的誤解)。

因此,您需要強制切換到要在其上運行的任何線程。 例如,使用Task.Run切換到線程池,或使用TaskScheduler.FromCurrentSynchronizationContext在UI上運行。

如果您await任務,則可以保證在await之前設置的同步上下文中繼續執行任務。 這可能就是您想要的。

暫無
暫無

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

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