使用线程在后台计算值

本文关键字:计算 后台 线程 | 更新日期: 2023-09-27 18:15:15

我正在编写一个从远程计算机查询信息的程序。WMI,注册表等。我已经完成了大部分,但是没有线程,它运行得很慢。(我假设它在移动到下一个请求之前等待远程机器对每个请求的响应)。

我已经阅读了不同的线程方法。线程类,后台worker类,任务类。我可以线程所有的查询没有任何问题,但得到所有的信息回主线程,所以它可以格式化和显示在主XAML窗口上的richtextboxes信息。我一直得到错误,我不能访问变量,因为它们正在被其他线程使用,等等。

谁能给我一些关于如何管理/返回由其他线程计算/检索变量的见解?我看过很多关于线程的视频和文章,但是我找不到任何真正解释线程是如何工作的,以及我应该如何知道何时可以和不可以从不同的线程访问变量,等等。

使用线程在后台计算值

线程是硬件的低级抽象,而任务提供类似的异步工作,但也允许返回结果、异常管理等。默认情况下,在Windows UI中,你不能修改UI元素,除非你在创建它的线程上。BackgroundWorker类是一个较老的helper类,它帮助你将结果封送回UI线程。

Tasks现在提供了一种更直接的方法来处理这个问题。在任务中执行工作代码,然后将更新UI的代码放在任务的延续中。诀窍是告诉continuation在原始UI线程上运行,即UI的同步上下文。否则,它将默认为先前Task的上下文(默认为线程池)

下面是一个例子,执行DoWork()方法作为一个任务,然后用任务的结果更新UI上的TextBlock。因为Button_Click是从UI中调用的,所以它的上下文是UI线程。我们只需将该上下文传递给ContinueWith()方法,以在该上下文中执行延续代码。

private void Button_Click(object sender, RoutedEventArgs e)
{
    var t = Task.Run(() => DoWork());
    t.ContinueWith(
        // take the result of the Task and update the UI
        completedTask => Output.Text = completedTask.Result.ToString()
        // tell the Task Continuation to run on the original UI context
        , TaskScheduler.FromCurrentSynchronizationContext()
        );
}
private int DoWork()
{
    return 1;
}

这是一个标准的windows UI问题(WinForms, XAML) -数据来自另一个线程而不是UI线程。你可以在这篇MSDN文章和这篇WPF XAML文章中了解如何避免WinForms问题。. net 4中的任务并行库(不再那么新了)。X提供了一个非常好的、简单的同步上下文。你可以在这里阅读如何使用它:任务同步上下文。

还有一个新的async/await概念,但我还没有使用它,所以我不能说任何关于它。

线程和任务(ing)在后台是两个不同的东西,但是IMHO任务对于琐碎的异步操作已经足够了。我发现这个库非常容易使用,主要是因为流畅的API和同步上下文支持。关于任务并行库的更多信息可以在这里找到。