簡體   English   中英

什么是PushFrame需要?

[英]For what is PushFrame needed?

我遇到了Dispatcher對象的PushFrame方法。 它是方法的簡化版本:

public void PushFrame(DispatcherFrame frame)
{
    // Stuff
    _frameDepth++;

    while(frame.Continue)
    {
        // Getting and dispatching messages
    }

    _frameDepth--;
    // Stuff
}

換句話說,它只是打開新的消息處理循環。 但我真的無法理解這種方式的好處。 PushFrame用於什么目的? 它的用法有很好的例子嗎? 至於我,似乎這種方法會導致不明顯的錯誤。

它是WPF程序中調度程序循環的必要管道。 Windows上的每個GUI程序都有一個,它是生產者 - 消費者問題的通用解決方案。 操作系統和其他程序生成的地方以及WPF程序的UI線程消耗。 對GUI應用程序的硬性要求,實現GUI的庫代碼從不是線程安全的。 您可以在此處輕松查看循環,您無法看到循環清空的線程安全隊列,它內置於操作系統中。

通過調用Application.Run()啟動循環。 在WPF應用程序中不容易看到,它是在App.xaml文件的大多數應用程序中自動生成的。 推動第一個“框架”,只要它停留在循環內,你的應用程序就會繼續運行。 在事件處理程序上設置斷點時,您將始終在“調用堆棧”調試器窗口中看到它。 關閉應用程序的MainWindow是循環結束的正常方式。 這反過來導致Run()方法返回,終止UI線程,終止進程。

在某些情況下,您希望擁有嵌套的調度程序循環。 一個“模態循環”。 您每天使用的這種模態循環的一個示例是當您在窗口角上單擊並拖動鼠標時。 現在,所有鼠標和鍵盤輸入都會更改窗口大小或位置,它們不再用於以正常方式操作UI。 釋放鼠標會終止該循環。 這個調度程序循環內置在操作系統中,它不是由WPF完成的。

但是WPF也可以用於這種模態循環。 規范示例是Window.ShowDialog()方法。 在關閉對話框之前,該方法不會返回。 由WPF內部再次調用PushFrame()實現。 只需使用調試器進行嘗試,您將在“調用堆棧”窗口中看到兩個PushFrame調用。 第一個是ShowDialog()調用的那個,第二個是Application.Run()調用的那個。 如果您的對話框依次顯示對話框,您將獲得更多。

一個不太明顯的例子是在UI線程上調用Dispatcher.Invoke()。 在調用的方法返回之前不返回的方法。 通常有點像一個bug,但沒有令人信服的理由不允許它。 警告可能是恰當的,模態循環非常危險。 他們有訣竅造成重新入侵的錯誤 使DoEvents()方法如此臭名昭着的錯誤。 ShowDialog()禁用UI中所有其他窗口的一個重要原因。

PushFrame用於什么目的?

它在內部用於將幀推送到當前的調度程序。 調度程序隊列的詳細工作方式是一個很大的主題,但以下答案應該會有所幫助。

了解Dispatcher隊列

它的用法有很好的例子嗎?

例如,當您出於某種原因想要同步調用異步方法並繼續泵送消息,直到任務完成。 您將在GitHub上的Stephen Cleary的AsyncCTPUtil庫中找到具體的示例實現: https//github.com/StephenCleary/AsyncCTPUtil/blob/master/AsyncTestUtilities/WpfContext.cs

有關更多信息,請參閱他的答案:

如何同步運行異步Task <T>方法?

您還可以參考以下鏈接: https//social.msdn.microsoft.com/Forums/vstudio/en-US/650e69f9-5f4d-4d77-8107-93fb6646f26d/solved-block-synchronous-method-while-waiting -用於-異步法對完成?論壇= WPF

暫無
暫無

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

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