淺談Silverlight 跨線程的使用詳解
新建SL4 應(yīng)用程序,在MainPage下添加代碼:
<Button x:Name="btnThread1" Click="btnThread1_Click">Thread1</Button>
后臺(tái)代碼為:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
MessageBox.Show("Hello World");
}).Start();
}
如果你運(yùn)行程序,點(diǎn)擊按鈕,會(huì)得到下面的異常。

這個(gè)問題的原因很簡(jiǎn)單:一個(gè)線程嘗試調(diào)用另一個(gè)線程的方法 解決這個(gè)異常的方式很簡(jiǎn)單,
1:使用DependencyObject.Dispatcher.BeginInvoke 方法:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Hello World");
});
}).Start();
}
2:使用SynchronizationContext 對(duì)象
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,所以還是會(huì)跑出異常。
所以提出了第三種方案:
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#下注冊(cè)表操作的一個(gè)小細(xì)節(jié)
c#下注冊(cè)表操作的一個(gè)小細(xì)節(jié)...2007-11-11
C# Record構(gòu)造函數(shù)的行為更改詳解
C# 9 中的record類型是僅具有只讀屬性的輕量級(jí)、不可變數(shù)據(jù)類型(或輕量級(jí)類),下面這篇文章主要給大家介紹了關(guān)于C# Record構(gòu)造函數(shù)的行為更改的相關(guān)資料,需要的朋友可以參考下2021-08-08
C#使用ADO.Net部件來訪問Access數(shù)據(jù)庫的方法
數(shù)據(jù)庫的訪問是所有編程語言中最重要的部分,C#提供了ADO.Net部件用于對(duì)數(shù)據(jù)庫進(jìn)行訪問。本文從最簡(jiǎn)單易用的微軟Access數(shù)據(jù)庫入手討論在C#中對(duì)數(shù)據(jù)庫的訪問。2015-09-09
C#實(shí)現(xiàn)發(fā)送手機(jī)驗(yàn)證碼功能
之前基于c#實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能很復(fù)雜,真正做起來也就那回事,不過就是一個(gè)post請(qǐng)求就可以實(shí)現(xiàn)的東西,今天小編把思路分享到腳本之家平臺(tái),供大家參考下2017-06-06
Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用
這篇文章主要為大家介紹了Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07

