Silverlight中的线程处理技术详解
立即解锁
发布时间: 2025-08-25 01:57:37 阅读量: 3 订阅数: 13 

### Silverlight 中的线程处理技术详解
在 Silverlight 开发中,线程处理是一个关键的技术领域,它涉及到如何高效地管理和执行多线程任务,以确保用户界面的响应性和数据的一致性。本文将详细介绍 Silverlight 中线程处理的相关技术,包括 Dispatcher、BackgroundWorker 类、共享数据处理以及定时器的使用。
#### 1. Dispatcher 的使用
在 Silverlight 中,用户界面元素只能在创建它们的线程上进行修改。为了解决跨线程访问用户界面元素的问题,我们可以使用 Dispatcher。
##### 1.1 Dispatcher 的功能
DependencyObject 类是 Silverlight 中许多类的基类,它有一个重要的属性 Dispatcher。每个对象都有一个 Dispatcher 属性,该属性提供了两个重要的功能:
- **CheckAccess 方法**:用于测试当前线程是否可以修改对象。如果当前线程与 Dispatcher 所属的线程相同,CheckAccess 方法将返回 true。
- **BeginInvoke 方法**:用于将代码排队到 Dispatcher 的线程上执行,从而解决跨线程访问用户界面对象的问题。
##### 1.2 使用 Dispatcher 修改用户界面
以下是一个使用 Dispatcher 修改用户界面的示例代码:
```csharp
void responseHandler(IAsyncResult asyncResult)
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
StreamReader reader = new StreamReader(response.GetResponseStream());
string result = "";
// read and process file
Dispatcher.BeginInvoke(delegate() { resultTextBox.Text = result; });
}
```
在这个示例中,我们使用 BeginInvoke 方法创建了一个匿名的零参数方法,用于更新用户界面上的文本框。
如果需要执行带有参数的方法,可以使用 BeginInvoke 的另一种形式,该形式接受一个参数数组作为第二个参数。
如果不确定调用线程是否为用户界面线程,可以结合使用 CheckAccess 和 BeginInvoke 来修改用户界面:
```csharp
void modifyUserInterface()
{
if(Dispatcher.CheckAccess())
{
resultTextBox.Text = "modified from UI thread";
} else {
Dispatcher.BeginInvoke(
delegate() {
resultTextBox.Text = "modified from non-UI thread";
}
);
}
}
```
#### 2. BackgroundWorker 类的使用
如果需要在单独的线程上执行工作,使用 BackgroundWorker 类是最简单的方法。该类位于 System.ComponentModel 命名空间中,它可以在后台线程上执行工作,同时保持用户界面的响应性,并提供事件来报告工作进度。
##### 2.1 BackgroundWorker 的属性
| 属性 | 类型 | 描述 |
| ---- | ---- | ---- |
| CancellationPending | bool | 当应用程序尝试通过调用 CancelAsync 方法取消 BackgroundWorker 时为 true。 |
| IsBusy | bool | 当 BackgroundWorker 的任务正在进行时为 true(在调用 RunWorkerAsync 之后,并且任务未完成或未取消)。 |
| WorkerReportsProgress | bool | 当 BackgroundWorker 配置为通过 ProgressChanged 事件处理程序报告进度时为 true。 |
| WorkerSupportsCancellation | bool | 当 BackgroundWorker 能够通过 CancelAsync 方法取消时为 true。 |
##### 2.2 BackgroundWorker 的事件
BackgroundWorker 有三个事件:
- **DoWork**:包含要在后台线程上执行的工作代码。
- **ProgressChanged**:用于处理进度更改通知,通常用于在用户界面上显示状态指示器。
- **RunWorkerCompleted**:当工作完成时触发。
需要注意的是,应避免在 DoWork 事件中更新用户界面,而是使用 ProgressChanged 和 RunWorkerCompleted 事件来更新用户界面。
##### 2.3 使用 BackgroundWorker 的示例
以下是一个使用 BackgroundWorker 的示例代码:
```csharp
public void performLengthyOperation(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = (BackgroundWorker)sender;
CustomWorkerArgs args = (CustomWorkerArgs)e.Argument;
e.Result = args;
for (int i = 1; i <= 10; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
Thread.Sleep(args.sleepTime / 10);
bw.ReportProgress(i * 10, args);
}
}
}
class CustomWorkerArgs
{
public int index;
public int sleepTime;
}
private void buttonTask_Click(object sender, RoutedEventArgs e)
{
int index = Convert.ToInt32(((Button)sender).Tag);
if (workers[index] != null)
{
resultBoxes[index].Text = "Cancelling...";
workers[index].CancelAsync();
bwButtons[index].Content = "Start";
}
else
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
work
```
0
0
复制全文
相关推荐









