【问题标题】:create_Task(): The application called an interface that was marshalled for a different threadcreate_Task():应用程序调用了为不同线程编组的接口
【发布时间】:2018-05-21 19:57:18
【问题描述】:

我有一个 UWP UI,它调用需要一段时间才能执行的本机代码。完成后,UI 需要更新。这是我的代码:

auto runOpti = create_task([this] { runOptimation(); });
runOpti.then([this]{postOptimation(); });

postOptimation 例程包括以下行:

backwordCheckBox->IsChecked = params->backwards;

像这样执行会在标题中出现错误。

如何让 postOptimation 在 UI 线程中运行?

谢谢

【问题讨论】:

  • 这段代码显然已经在一个任务上运行,所以不需要 create_task 来创建另一个。注意调试器中的堆栈跟踪,看看它是如何到达那里的。小心这样的代码,你的用户很快就会厌倦看着草生长,开始玩纸牌游戏,你的优化不会完成。

标签: c++ multithreading uwp


【解决方案1】:

使用Dispatcher属性的Invoke方法:backwordCheckBox->Dispatcher->Invoke。

自从我用 .net 做任何事情以来,我已经安静了一段时间了,我不记得如何从 lambda 创建一个动作,但你就是这样做的。

【讨论】:

    【解决方案2】:

    此代码将确保操作在与您的“backwordCheckBox”控件关联的 UI 线程上执行:

    backwordCheckBox->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
        ref new Windows::UI::Core::DispatchedHandler ([this, params]
    {
        backwordCheckBox->IsChecked = params->backwards;
    }));
    

    【讨论】:

      【解决方案3】:

      Sornel 的好建议!这是有效的:

      postOptimation 中的代码:

      Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High,
          ref new Windows::UI::Core::DispatchedHandler([this]()
      {
      
          backwordCheckBox->IsChecked = params->backwards;
      
      }));
      

      【讨论】:

        【解决方案4】:

        您可以使用采用task_continuation_context.then() 的重载,并将其设置为task_continuation_context::get_current_winrt_context()

        使用Dispatcher(其他答案)也可以,但这应该与 PPL 组合得更好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-05
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          • 2013-10-20
          相关资源
          最近更新 更多