![](/img/trans.png)
[英]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.