是否可以将Task <t>(带有返回值)传递给现有的(即已经运行的)Thread </t>

时间:2013-12-04 15:00:07

标签: c# wpf task async-await synchronizationcontext

在wpf中我有两个不同线程的窗口 从线程A中的窗口A'开始,我想在窗口B'的Tread B中启动一个任务,并等待线程A中的返回值。
它假设有可能,但如何?
你知道一个例子吗?

2 个答案:

答案 0 :(得分:5)

多个WPF UI线程是一种非常高级的方案。

你应该能够通过让线程B公开任务工厂来实现它:

 TaskFactory _taskFactory;
 public TaskFactory TaskFactory { get { return _taskFactory; } }

在线程B的创业公司的某个时刻做了类似的事情:

 // Startup code running on Thread B
 _taskFactory = new TaskFactory(
     TaskScheduler.FromCurrentSynchronizationContext());

然后你可以从线程A使用工厂,允许线程A(或任何人)将工作排队到线程B:

 await _threadB.TaskFactory.StartNew(() =>
 {
   ...
 });

答案 1 :(得分:0)

据我了解,实际问题是当两个窗口在不同的线程中运行时,如何从窗口A启动对窗口B的操作。

在这种情况下,您可以使用SynchronizationContext.PostSynchronizationContext.Send在第二个窗口的同步上下文中启动操作,而无需启动任务。发送将阻止调用线程,直到处理回调,而Post将立即返回。这使Post更适合该场景。

最终结果与在线程B上创建任务相同。回调将在线程B上执行,但现在您可以避免创建和分派任务的工作,并且它需要更少的代码。

为了使这个整洁,您可以在创建Window B的新实例时存储对当前Synchronization上下文的引用,并在Windows B中的包装器方法中使用它:

public partial class WindowB : Window
{
    private SynchronizationContext _context;

    ...

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);
        _context = SynchronizationContext.Current;
    }

    public void PostAction(string data)
    {
        _context.Post(ActualAction,data);
    }

    private void ActualAction(object state)
    {
        Title = state.ToString();

    }
}