UI线程,工作线程和两者之间的通信

时间:2012-08-31 18:22:49

标签: wpf multithreading mvvm

我的应用程序使用UI线程和另一个线程在后台执行操作,并使用这些操作的结果更新UI。

这一切都运作良好。但是,在一次操作中,我需要用户要求输入一些值。序列:

  • 运行UI线程
  • 命令 - >第二个线程开始(让我们称之为工作线程)在后台工作
  • 工作线程在按顺序执行操作时向UI发送状态信息
  • 在一个特定操作期间,工作线程已停止
  • 发送一条消息,必须显示该视图,以便用户选择一个选项
  • UI线程订阅了此类消息,因此它显示了一个视图
  • 用户完成选择,并关闭视图
  • 工作线程接收用户选择,并继续执行
  • 工作线程完成

开始新的thead的代码:

Thread thread = new Thread(Convert);
thread.SetApartmentState(ApartmentState.STA); // avoid "The calling thread must be STA" exception
thread.Start();

从工作线程向UI线程发送状态信息的代码:

Application.Current.Dispatcher.BeginInvoke(
    System.Windows.Threading.DispatcherPriority.Normal,
    (Action<OperationStatus>)delegate(OperationStatus operation)
        {
            OperationList.Add(operation);
        }, status);

要求用户确认的代码:

在MainViewModel中,在执行工作线程期间:

// create ViewModel, that will be used as DataContext for dialog view
var vm = new SelectOptionViewModel(OptionList);
// subscribe to Close event, to get user selection
vm.Close += (s, e) =>
{
    _option = vm.SelectedOption;
};

AppMessages.DialogScreen.Send(vm);

在MainView中,在执行工作线程期间:

AppMessages.DialogScreen.Register(this, vm =>
    {
        SelectOptionView view = new SelectOptionView();
        view.DataContext = vm;
        // view.Owner = this; // raises exeption about cross-threading
        view.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
        view.ShowDialog();
    });

问题是如何将对话框视图设置为在父视图(MainView)中居中显示?设置view.Owner到“this”是不可能的,因为“this”是在UI线程上创建的。

我应该在应用程序中更改中心对话框视图,同时保留定义的序列顺序?

2 个答案:

答案 0 :(得分:1)

您是否考虑过使用background worker

答案 1 :(得分:0)

什么线程执行注册labda创建对话框?

它必须是UI线程。

如果要在UI上下文中执行某些代码并将结果返回到工作线程,可以使用SynchronizationContext和Task

请参阅示例here