【C#學習筆記】使用C#中的Dispatcher

form:https://www.jianshu.com/p/0714fc755988

之前的文章說過了如何使用BackgroundWorker,今天要說的是WPF程序員處理多線程的另外一個方式 - Dispatcher

當我們打開一個WPF應用程序即開啟了一個進程,該進程中至少包含兩個線程。

  • 一個線程用于處理呈現:隱藏在后臺運行
  • 一個線程用于管理用戶界面:接收輸入、處理事件、繪制屏幕以及運行應用程序代碼。即UI線程。

在UI線程中有一個Dispatcher對象,管理每一個需要執行的工作項。Dispatcher會根據每個工作項的優先級排隊。

向Dispatcher列隊中添加工作項時可指定10個不同的級別。

那么問題來了,如果遇到耗時操作的時候,該操作如果依舊發生在UI線程中,Dispatcher 列隊中其他的需要執行的工作項都要等待,從而造成界面假死的現象。為了加快響應速度,提高用戶體驗,我們應該盡量保證Dispatcher 列隊中工作項要。所以,對于耗時操作,我們應該開辟一個新的子線程去處理,在操作完成后,通過向UI線程的Dispatcher列隊注冊工作項,來通知UI線程更新結果。

Dispatcher提供兩個注冊工作項的方法:InvokeBeginInvoke。這兩個方法均調度一個委托來執行。Invoke 是同步調用,也就是說,直到 UI 線程實際執行完該委托它才返回。BeginInvoke是異步的,將立即返回。

  • Dispatcher實際上并不是多線程
  • 子線程不能直接修改UI線程,必須通過向UI線程中的Dispatcher注冊工作項來完成
  • Dispatcher 是單例模式,暴露了一個靜態的CurrentDispatcher方法用于獲得當前線程的Dispatcher
  • 每一個UI線程都至少有一個Dispatcher,一個Dispatcher只能在一個線程中執行工作。
  • 開啟新線程的方法很多,比如delegate.BeginInvoke()的方式開啟的新線程。

Delegate.Invoke: ? ? ? ? ?Executes synchronously, on the same thread.
Delegate.BeginInvoke: Executes asynchronously, on a threadpool thread.

示例程序

XAML

<Window x:Class="DispatcherExample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="160" Width="300"><StackPanel><ProgressBar Name="progressBar" Height="20" Width="250" Margin="10"></ProgressBar><TextBox Name="textBox" Width="50" Height="20" HorizontalAlignment="Center"></TextBox><Button Name="btnProcess" Width="100" Click="btnProcess_Click" Margin="5">Start</Button><Button Name="btnCancel" Width="100" Click="btnCancel_Click" Margin="5">Cancel</Button></StackPanel>
</Window>

C#

namespace DispatcherExample
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}Thread taskThread;private void btnProcess_Click(object sender, RoutedEventArgs e){taskThread = new Thread(DoTask);taskThread.Start();}private void btnCancel_Click(object sender, RoutedEventArgs e){taskThread.Abort();MessageBox.Show("Background task finished normally", "info");this.progressBar.Value = 0;this.textBox.Text = null;}private void DoTask(){Int64 InputNum = (Int64)100;for (Int64 i = 0; i < InputNum; i++){Thread.Sleep(100);this.Dispatcher.BeginInvoke((Action)delegate(){this.progressBar.Value = i;this.textBox.Text = i.ToString();//顯示百分比值});}MessageBox.Show("Background task has been canceled", "info");this.Dispatcher.BeginInvoke((Action)delegate(){this.progressBar.Value = 0;this.textBox.Text = null;});}}
}

演示

DispatcherExample.gif


作者:Jason_Yuan
鏈接:https://www.jianshu.com/p/0714fc755988
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
---------------------------------------------------------------------------------------------------------------------------

C#中的委托(delegate)用法簡介

委托 delegate是只有一個函數的特殊的類
委托對象的引用相當函數指針

delegate 聲明定義一種引用類型,該類型可用于將方法用特定的簽名封裝。委托實例封裝靜態方法或實例方法。

委托大致類似于 C++ 中的函數指針;但是,委托是類型安全和可靠的。

委托使您得以將函數作為參數傳遞。委托的類型安全要求作為委托傳遞的函數擁有同委托聲明相同的簽名

使用委托使程序員可以將方法引用封裝在委托對象內。

然后可以將該委托對象傳遞給某個方法,而不必在編譯時知道將調用哪個方法。與 C 或 C++ 中的函數指針不同,委托是面向對象、類型安全的?

委托聲明定義一種類型,它用一組特定的參數以及返回類型封裝方法。對于靜態方法,委托對象封裝要調用的方法。對于實例方法,委托對象同時封裝一個實例和該實例上的一個方法。如果您有一個委托對象和一組適當的參數,則可以用這些參數調用該委托。?
委托的一個有趣且有用的屬性是,它不知道或不關心自己引用的對象的類。任何對象都可以;只是方法的參數類型和返回類型必須與委托的參數類型和返回類型相匹配。這使得委托完全適合“匿名”調用

//例子1

class Program

{
??????? delegate bool CompareOp(int v1, int v2);
??????? static void Main(string[] args)
??????? {
??????????? CompareOp less = new CompareOp(Program.Less);
??????????? Console.WriteLine(less(1, 2).ToString());
??????????? Console.WriteLine("Test Delegate");
??????????? Console.ReadLine();
??????? }
??????? static public bool Less(int a, int b)
??????? {
??????????? return a < b;
??????? }
}

//例子2

delegate void MyDelegate(int i);?

class Program?
{?
? public static void Main()?
? {?
??? TakesADelegate(new??? MyDelegate( DelegateFunction ));?

? }?

? public static void TakesADelegate(MyDelegate SomeFunction)?
? {?
???? SomeFunction(21);?

?? }?

? public static void DelegateFunction (int i)
? {?
???? System.Console.WriteLine("Called by delegate with number: {0}.", i);?
?? }?
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458455.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458455.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458455.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

流媒體 關鍵詞解釋

流媒體 流媒體是指采用流式傳輸的方式在網上播放的媒體格式, 是邊傳邊播的媒體&#xff0c;是多媒體的一種! 然后就是大家需要了解的幾個關鍵詞 幀:視頻是由很多連續圖像組成, 每一幀就代表一幅靜止的圖像 GOP:&#xff08;Group of Pictures&#xff09;畫面組&#xff0c;一個…

[C#] 等待啟動的進程執行完畢

from: https://www.cnblogs.com/qqhfeng/p/4769524.html有能有時候我們啟動了一個進程&#xff0c;必須等到此進程執行完畢&#xff0c;或是&#xff0c;一段時間&#xff0c; 關閉進程后再繼續往下走。Example sample1 等待應用程序執行完畢 //等待應用程序執行完畢private vo…

html body標簽

table table 屬性&#xff1a; border &#xff1a;定義表格的邊框寬度&#xff0c;默認為0&#xff0c;即無邊框。<table border"1"> title &#xff1a;表格的提示信息&#xff0c;當鼠標移到表格上方時&#xff0c;所提示的信息。 cellpadding &#xff1a;…

創建字符串的方法

//創建一個字符串常量 NSString *str"字符串"; //創建一個空的字符對象 NSString *str1[[NSString alloc]init];//實例方法 NSString *str2[NSString string];//類方法 //快速創建一個字符串 NSString *str3[[NSString alloc]initWithString:"字符串"];//實…

DataReceivedEventHandler 委托 接收調用執行進程返回數據

https://msdn.microsoft.com/zh-cn/library/azure/system.diagnostics.datareceivedeventhandler備注創建 DataReceivedEventHandler 委托時&#xff0c;需要標識將處理該事件的方法。 若要將事件與事件處理程序關聯&#xff0c;請將該委托的一個實例添加到事件中。 除非移除了…

coreData

CoreData使用 創建步驟流程 第一步先創建.xcdatamodeld文件&#xff08;New File -> iOS -> Core Data ->Data Model&#xff09; 屏幕快照 2016-07-07 下午10.40.16.png名字雖然可以任意取&#xff0c;但最好還是取和自己存儲數據庫名字一樣的名字。這樣可讀性更高些…

命令行下mysql新建用戶及分配權限

創建用戶&#xff1a; CREATE USER usernamehost IDENTIFIED BY password; 說明:username – 你將創建的用戶名, host – 指定該用戶在哪個主機上可以登陸,如果是本地用戶可用localhost, 如 果想讓該用戶可以從任意遠程主機登陸,可以使用通配符%. password – 該用戶的登陸密…

PetaPoco初體驗(轉)

PetaPoco初體驗&#xff08;轉&#xff09; PetaPoco初體驗&#xff08;轉&#xff09;大部分轉自&#xff1a; http://landyer.com/archives/138 PetaPoco C#微型ORM框架&#xff0c;基本無需配置&#xff0c;僅由單個cs文件構成&#xff0c;支持.net3.5 .net4.0。 截稿時Peta…

iOS當中的設計模式

代理模式 應用場景&#xff1a;當一個類的某些功能需要由別的類來實現&#xff0c;但是又不確定具體會是哪個類實現。 優勢&#xff1a;解耦合 敏捷原則&#xff1a;開放-封閉原則 實例&#xff1a;tableview的 數據源delegate&#xff0c;通過和protocol的配合&#xff0c…

c#的dllimport使用方法詳解

DllImport是System.Runtime.InteropServices命名空間下的一個屬性類&#xff0c;其功能是提供從非托管DLL&#xff08;托管/非托管是微軟的.net framework中特有的概念&#xff0c;其中&#xff0c;非托管代碼也叫本地&#xff08;native&#xff09;代碼。與Java中的機制類似&…

each函數循環數據表示列舉,列舉循環的時候添加dom的方法

var dotBox $(#bannerNum);var item <li></li>;var itemSize $(#bannerBack p).length;var dotBoxWidth itemSize*24;$(#bannerBack p).each(function () { dotBox.append(<li></li>); dotBox.find(li).eq(0).addClass(current);});這里要根…

使用lxml代替beautifulsoup

深入使用過lxml的都會深深地喜歡上它,雖然BeautifulSoup很流行,但是深入了解lxml后,你就再也不會使用bs了 我覺得beautifulsoup不好用,速度也慢(雖然可以使用lxml作為解析器了).另外soup.find_all這種簡直就是手工時代的操作(很多人使用find find_all這幾個函數, 其實它們使用起…

QT調用dll且進入DLL src code調試

qt應用程序AA.exe調用qt寫的BB.DLL時&#xff0c;進入BB.DLL src code調試 1、debug生成AA.exe 2、將debug生成的AA.exe整包debug folder放到BB.dll的debug生成的文件夾中 3、設置BB.dll這個project&#xff1a;項目----運行-----Executable中選擇BB.dll的debug文件夾中的AA.ex…

php安裝編譯時 configure: error: Cannot find OpenSSL's evp.h

yum install error: protected multilib versions errorsudo yum downgrade openssl 降級sudo yum install openssl-devel 另外參考yum install -y ncurses-devel yum install openssl openssl-develyum install openssl openssl-devel --setoptprotected_multilibfalse ln -s …

laravel項目中css樣式表的背景圖片不顯示

剛學laravel&#xff0c;遇到了很多坑&#xff0c;感覺laravel是挺強大的。 建好后臺項目&#xff0c;奈何css樣式表的背景圖片不顯示 .mainhd {background: url(../images/sky/body_bg.png) repeat-x 0px 0px; } 按理上面的寫法沒錯&#xff0c;因為是從別的后臺搬過來的&…

KVC KVO

1、KVC&#xff0c;即是指 NSKeyValueCoding&#xff0c;一個非正式的Protocol&#xff0c;提供一種機制來間接訪問對象的屬性。而不是通過調用Setter、Getter方法訪問。KVO 就是基于 KVC 實現的關鍵技術之一。 Demo&#xff1a; interface myPerson : NSObject { …

VS2010中 C++創建DLL圖解

一、DLL的創建 創建項目: Win32->Win32項目&#xff0c;名稱&#xff1a;MyDLL 選擇DLL (D) ->完成. 1、新建頭文件testdll.htestdll.h代碼如下&#xff1a;#ifndef TestDll_H_#define TestDll_H_#ifdef MYLIBDLL#define MYLIBDLL extern "C" _declspec(dllimp…

js理解 call( ) | apply( ) | caller( ) | callee( )

被js的這幾個方法搞的this暈頭轉向&#xff0c;下定決心搞清楚&#xff1b;1、call( )和apply( ):兩者都可以將函數綁定到另外一個對象上去運行&#xff0c;只是參數的傳遞方式不同&#xff0c;兩者都可以使當前函數擁有另一個對象的屬性和方法&#xff0c;實現js下的繼承&…

上傳SVN丟失.a文件的問題

iOS項目上傳到svn中&#xff0c;.a文件丟失 用Cornerstone工具&#xff0c;解決這個問題 1.打開Cornerstone左上角&#xff0c;點Cornerstone->Preferences->Subversion 2.Global lgnores下面有一個Use default global ignores 默認這里方框中會打鉤&#xff08;這就是.a…

使用公用表表達式的遞歸查詢

微軟從SQL2005起引入了CTE(Common Table Expression)以強化T-SQL。公用表表達式 (CTE) 具有一個重要的長處&#xff0c;那就是可以引用其自身。從而創建遞歸 CTE。遞歸 CTE 是一個反復運行初始 CTE 以返回數據子集直到獲取完整結果集的公用表表達式。 當某個查詢引用遞歸 CTE 時…