Как синхронизировать интерфейс и получить доступ к объектам из другого потока? - PullRequest
0 голосов
/ 17 ноября 2011

Я довольно новичок в параллельном программировании и потоках.Я хочу рассчитать и добавить ряды к диаграмме, что, к сожалению, довольно трудоемкая задача.Поэтому я хотел бы показать экран загрузки между тем:

(.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 и настройкам из другого потока.

Как получить доступ и изменить пользовательский интерфейс в другом потоке и как передавать объекты, созданные в одном потоке, в другой?Можете ли вы привести аналогичный пример того, что я пытаюсь сделать?

Ответы [ 2 ]

2 голосов
/ 17 ноября 2011

Из потока, не являющегося пользовательским интерфейсом, чтобы обновить элемент управления в потоке пользовательского интерфейса, необходимо выполнить:

Dispatcher.Invoke(...);  OR
Dispatcher.BeginInvoke(...);

Начните здесь: Создание более отзывчивых приложений с помощью диспетчера
и немного здесь: Руководство для начинающих по созданию потоков в .NET: Часть 5 из n
и небольшой пример: Библиотека параллельных задач: 1 из n

0 голосов
/ 17 ноября 2011

Вы должны сделать, может быть, это

EDIT / Update

у меня это нормально работает, но поток 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();
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...