【问题标题】:Windows universal C++ concurrencyWindows 通用 C++ 并发
【发布时间】:2015-10-25 14:22:46
【问题描述】:

我有以下模式:

task<Param1^> MyClass::MethodA(String^ s)
{
     return create_task([this, s]
     {

         ....

         IAsyncOperation<Param1^>^ result = SystemMethod1ReturningParam1(...);

         return result;
     });
}

IAsyncOperation<Param2^>^ MyClass::MethodB(String^ s)
{
    return create_async([this, s]
    {
         return MethodA(s).then([this](task<Param1^> t)
         {
             Param1^ p1 = t.get();

             ....

             Param2^ result = SystemMethod2ReturningParam2(p1);
             return result ;
         });
    });
}

我调用 public MethodB 调用私有 MethodA。 Param1 是我无法更改的标准枚举。 MethodA create_task 我需要返回错误条件。我不能返回空值。 MethodB 也需要返回错误条件。

从这两种方法返回错误的最佳方法是什么?

SystemMethod1ReturningParam1 和 SystemMethod2ReturningParam2 是框架系统方法,可以抛出异常。我在哪里抓到他们?

【问题讨论】:

  • 我不想这么说,但是通过 WinRT 学习 C++ 或并发性是一种不好的做法。尝试先使用标准来理解它..
  • 我非常精通经典C++和经典并发。
  • 只需rtfm first,然后提出一个重点问题,表明您正在尝试使用现有的东西。
  • 该代码肯定不是 C++。它看起来像一个叫做 C++/CLI 的东西,完全不同。

标签: concurrency win-universal-app c++-cx


【解决方案1】:

如果您担心异常,则应始终使用基于任务的延续并将对task.get() 的调用包装在try/catch 中。

请注意,下面的代码(和其他 C++ 代码)会抛出 std::exception,但如果您正在与 WinRT 组件交互并且希望传播异常,则必须重新抛出 Platform::Exception 值。

concurrency::task<int> throw_async()
{
  return concurrency::create_task([]
  {
    throw std::exception("oops");
    return -1;
  });
}

void test_value()
{
  // This will crash inside PPL runtime due to unobserved exception
  throw_async().then([](int x)
  {
    OutputDebugString(L"You'll never see this\r\n");
  });
}

void test_task()
{
  // This will handle the exception correctly
  throw_async().then([](concurrency::task<int>& t)
  {
    OutputDebugString(L"You'll see this\r\n");
    try
    {
      auto val = t.get();
      OutputDebugString(L"You'll never see this\r\n");
    }
    catch (std::exception& ex)
    {
      auto error = ex.what(); // "oops"
      // Need to re-throw if this crosses the WinRT ABI boundary.
      // Conversion of 'error' to Platform::String^ omitted for brevity
      throw ref new Platform::FailureException(/* error */);
    }
  });
}

【讨论】:

  • 这种方式好像不行。如果我抛出 std::exception ,当我尝试访问 task.get 时,我会用 E_FAIL 和“未指定的错误”作为描述捕获 Pltform::exception。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
  • 2014-11-21
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
相关资源
最近更新 更多