淺談Silverlight 跨線程的使用詳解
新建SL4 應用程序,在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();
}
如果你運行程序,點擊按鈕,會得到下面的異常。

這個問題的原因很簡單:一個線程嘗試調(diào)用另一個線程的方法 解決這個異常的方式很簡單,
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();
}
但是這兩者都有一個缺陷,假設有多個線程,例如多線程的多線程:
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,但是因為context并不是UI線程的SynchronizationContext,所以還是會跑出異常。
所以提出了第三種方案:
1:新建靜態(tài)類UISynchronizationContext,代碼如下:
/// <summary>
/// UI線程的SynchronizationContext
/// </summary>
public static class UISynchronizationContext
{
public static SynchronizationContext Context { get; set; }
}
修改App.Xaml.cs 代碼的構造函數(shù),在構造App的時候設置
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();
}
使用的時候只需要:
private void btnThread1_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
new Thread(() =>
{
UISynchronizationContext.Context.Post((state) =>
{
MessageBox.Show("Hello World");
}, null);
}).Start();
}).Start();
}
其實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();
相關文章
C#使用XmlDocument或XDocument創(chuàng)建xml文件
這篇文章主要為大家詳細介紹了C#使用XmlDocument或XDocument創(chuàng)建xml文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10
C# StreamReader類實現(xiàn)讀取文件的方法
這篇文章主要介紹了C# StreamReader類實現(xiàn)讀取文件的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
使用C#實現(xiàn)阿拉伯數(shù)字到大寫中文的轉(zhuǎn)換
這篇文章主要介紹了C#實現(xiàn)阿拉伯數(shù)字轉(zhuǎn)為大寫中文的實現(xiàn)代碼,需要的朋友可以參考下2007-03-03

