淺談Silverlight 跨線程的使用詳解
新建SL4 應(yīng)用程序,在MainPage下添加代碼:
<Button x:Name="btnThread1" Click="btnThread1_Click">Thread1</Button>
后臺代碼為:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
MessageBox.Show("Hello World");
}).Start();
}
如果你運(yùn)行程序,點(diǎn)擊按鈕,會得到下面的異常。
這個(gè)問題的原因很簡單:一個(gè)線程嘗試調(diào)用另一個(gè)線程的方法 解決這個(gè)異常的方式很簡單,
1:使用DependencyObject.Dispatcher.BeginInvoke 方法:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Hello World");
});
}).Start();
}
2:使用SynchronizationContext 對象
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
SynchronizationContext context = SynchronizationContext.Current;
new Thread(() =>
{
context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}
但是這兩者都有一個(gè)缺陷,假設(shè)有多個(gè)線程,例如多線程的多線程:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
SynchronizationContext context = SynchronizationContext.Current;
new Thread(() =>
{
context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}).Start();
}
雖然這里保存了context,但是因?yàn)閏ontext并不是UI線程的SynchronizationContext,所以還是會跑出異常。
所以提出了第三種方案:
1:新建靜態(tài)類UISynchronizationContext,代碼如下:
/// <summary>
/// UI線程的SynchronizationContext
/// </summary>
public static class UISynchronizationContext
{
public static SynchronizationContext Context { get; set; }
}
修改App.Xaml.cs 代碼的構(gòu)造函數(shù),在構(gòu)造App的時(shí)候設(shè)置
UISynchronizationContext.Context = SynchronizationContext.Current;
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
//保存UI線程同步上小文
UISynchronizationContext.Context = SynchronizationContext.Current;
InitializeComponent();
}
使用的時(shí)候只需要:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
new Thread(() =>
{
UISynchronizationContext.Context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}).Start();
}
其實(shí)Silverlight 已經(jīng)提供了相似功能的類了,它就是
System.Windows.Deployment
你完全可以將上面的代碼修改為:
new Thread(() =>
{
new Thread(() =>
{
//UISynchronizationContext.Context.Post((state) =>
// {
// MessageBox.Show("Hello World");
// }, null);
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Hello World");
});
}).Start();
}).Start();
相關(guān)文章
C#使用XmlDocument或XDocument創(chuàng)建xml文件
這篇文章主要為大家詳細(xì)介紹了C#使用XmlDocument或XDocument創(chuàng)建xml文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10C#實(shí)現(xiàn)人民幣大寫轉(zhuǎn)換示例代碼
這篇文章主要介紹了C#實(shí)現(xiàn)人民幣大寫轉(zhuǎn)換,需要的朋友可以參考使用2013-12-12C#服務(wù)端圖片打包下載實(shí)現(xiàn)代碼解析
這篇文章主要介紹了C#服務(wù)端圖片打包下載實(shí)現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07C# StreamReader類實(shí)現(xiàn)讀取文件的方法
這篇文章主要介紹了C# StreamReader類實(shí)現(xiàn)讀取文件的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01使用C#實(shí)現(xiàn)阿拉伯?dāng)?shù)字到大寫中文的轉(zhuǎn)換
這篇文章主要介紹了C#實(shí)現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)為大寫中文的實(shí)現(xiàn)代碼,需要的朋友可以參考下2007-03-03C# 使用SDL2實(shí)現(xiàn)Mp4文件播放音視頻操作
這篇文章主要介紹了C# 使用SDL2實(shí)現(xiàn)Mp4文件播放音視頻操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12