亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Task.Delay 會破壞線程的 STA 狀態?

為什么 Task.Delay 會破壞線程的 STA 狀態?

C#
心有法竹 2022-12-24 09:44:16
介紹這是一個很長的問題!您會在開始時找到有關該問題的一些背景知識,然后是代碼示例,這些示例已針對表示形式進行了簡化,然后是問題。請按照您認為適合您的任何順序閱讀!背景資料我正在為與 STA COM 通信的應用程序編寫概念驗證部分。這部分應用程序需要在單線程單元 (STA) 上下文中運行,以便與所述 STA COM 通信。應用程序的其余部分在 MTA 上下文中運行。當前狀態到目前為止我想出的是創建一個包含循環的通信類,在 STA 中運行。while需要中繼到 COM 對象的工作從外部排隊到Communication類ConcurrentQueue。然后工作項在 while 循環中出列并執行工作。代碼上下文交流類這是一個static類,包含一個旨在在 STA 狀態下運行并檢查是否需要由 COM 完成某些工作并將工作分派給處理程序的循環。
查看完整描述

2 回答

?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

漢斯做到了。SynchronizationContext 從技術上講await,您的代碼正在中斷,因為. 但即使你寫了一個,也不夠。

這種方法的一個大問題是您的 STA 線程沒有啟動。STA 線程必須抽取 Win32 消息隊列,否則它們就不是 STA 線程。SetApartmentState(ApartmentState.STA)只是告訴運行時這是一個 STA 線程;它不會使其成為 STA 線程。您必須泵送消息才能使其成為 STA 線程。

您可以自己編寫消息泵,但我不知道有誰敢這樣做。大多數人從WinForms(la Hans 的回答)WPF安裝消息泵。也可以使用UWP 消息泵來執行此操作。

使用提供的消息泵的一個很好的副作用是它們還提供一個SynchronizationContext(例如WinFormsSynchronizationContextDispatcherSynchronizationContext),因此await可以自然地工作。此外,由于每個 .NET UI 框架都定義了一個“運行此委托”的 Win32 消息,因此底層 Win32 消息隊列也可以包含您想要排隊到您的線程的所有工作,因此顯式隊列及其“運行程序”代碼不再是必要的。


查看完整回答
反對 回復 2022-12-24
?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

因為在await Task.Delay()語句之后,您的代碼在 ThreadPool 線程之一內運行,并且由于 ThreadPool 線程在設計上是 MTA。


var th = new Thread(async () =>

        {

            var beforAwait = Thread.CurrentThread.GetApartmentState(); // ==> STA 


             await Task.Delay(1000);


            var afterAwait = Thread.CurrentThread.GetApartmentState(); // ==> MTA


        });


        th.SetApartmentState(ApartmentState.STA);

        th.Start();


查看完整回答
反對 回復 2022-12-24
  • 2 回答
  • 0 關注
  • 144 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號