[英]How to access a WinForms control from another thread i.e. synchronize with the GUI thread?
[英]How to synchronize UI and access objects from another thread?
我对并行编程和线程都很陌生。 我想计算并添加系列到图表,遗憾的是这是一项非常耗时的任务。 所以我想在此期间显示一个加载屏幕:
(.NET 4.0, WPF for UI)
ShowLoadingScreen(true);
CalculateAndUpdateChart(chartControl, settings);
ShowLoadingScreen(false);
...
private void ShowLoadingScreen(bool show) { loadingScreen.IsBusy = show; }
private void CalculateAndUpdateChart(ChartControl chart, ProductSettings settings)
{
chart.SomeSettings = ...
foreach(var item in settings.Items)
{
chart.Series.Points.Add(CalculateItem(item));
...
}
}
但当然这不起作用。 所以我想我需要在另一个线程中更新Chart控件。
ShowLoadingScreen(true);
Tash.Factory.StartNew(()=>{CalculateAndUpdateChart(chartControl, settings)});
ShowLoadingScreen(false);
但是,现在我得到了不同的错误,大多数我无法从另一个线程访问chartControl和设置。
如何从另一个线程访问和更改UI以及如何将在一个线程中创建的对象传递给另一个线程? 你能举一个类似的例子说明我想做什么吗?
从非UI线程更新UI线程上的控件,您必须执行以下操作:
Dispatcher.Invoke(...); OR
Dispatcher.BeginInvoke(...);
从这里开始: 使用Dispatcher构建更具响应性的应用程序
还有一点: .NET中的线程初学者指南:n的第5部分
和一个小例子: 任务并行库:n中的1个
你必须这样做
编辑/更新
这对我来说很好,但de gui线程在计算时仍然被阻止
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace TPLSpielwiese
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow() {
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
TaskScheduler taskUI = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory
.StartNew(() =>
{
this.ShowLoadingScreen(true);
}, CancellationToken.None, TaskCreationOptions.None, taskUI)
.ContinueWith((t) =>
{
//CalculateAndUpdateChart(chartControl, settings);
Thread.Sleep(1000);
}, CancellationToken.None, TaskContinuationOptions.None, taskUI)
.ContinueWith((t) =>
{
this.ShowLoadingScreen(false);
}, CancellationToken.None, TaskContinuationOptions.None, taskUI);
}
private Window loadScreen;
private void ShowLoadingScreen(bool showLoadingScreen) {
if (showLoadingScreen) {
this.loadScreen = new Window() {Owner = this, WindowStartupLocation = WindowStartupLocation.CenterOwner, Width = 100, Height = 100};
this.loadScreen.Show();
} else {
this.loadScreen.Close();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.