【问题标题】:C# WPF multithreading cannot return the actual value from Dispatcher.BeginInvoke in VS2013C# WPF 多线程无法从 VS2013 中的 Dispatcher.BeginInvoke 返回实际值
【发布时间】:2015-10-27 03:50:43
【问题描述】:

我想从 C# VS2013 WPF 中的线程获取返回值。

代码是:

int t = 0;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
    t = myFucntion(myObject) // if I do not use dispatcher, myObject cannot be accessed by the calling thread. 
));
return t;

为什么 t 总是 0 而不是返回实际值? 这里的解决方案对我不起作用。

WPF Dispatcher Invoke return value is always null

更新

Application.Current.Dispatcher.Invoke((() =>
        {
          t = myFunction(myObject));
        }));
return t;

但是,t 没有赋值给从 myFunction 返回的实际值。

【问题讨论】:

  • 我的猜测是该方法不会等待您的线程。所以它会在你的线程能够将结果存储在t之前返回0
  • 不确定您的意图是在更新任何 UI 项时使用 Dispatcher 对象。您可以移动逻辑来计算 t' either in BackgroudWorker` 或 Task 并在完成的事件中更新 Dispatch.BeginInvoke 中的 UI 元素(如果有)。
  • @user1672994,如果我不使用dispatcher,调用线程无法访问myObject。
  • 请参阅 OP 中的更新。

标签: c# wpf multithreading visual-studio action


【解决方案1】:

Dispatcher.BeginInvoke 是异步的。它将委托排队到消息循环后立即返回:

在指定的位置异步执行指定的委托 Dispatcher 关联的线程的优先级。

这意味着您有一个竞争条件,如果您运行足够多次,您甚至可能会看到 t 实际上包含 expected 值。

为了消除这种情况,如果您想等到代理在消息循环上运行,请改用Dispatcher.Invoke

Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, 
                                      new Action(() => t = myFunction()));

【讨论】:

  • 根据您的代码,我收到错误:WindowsBase.dll 中发生了“System.InvalidOperationException”类型的未处理异常。附加信息:调度程序处理暂停时无法执行此操作。
  • 请参阅 OP 中的更新。
  • t的值没有赋值给myFunction返回的实际值。
  • @user3750163 那么它返回什么值呢?
  • "t" 只能得到它的默认值 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多