异常处理,WinRT的C ++并行异步任务 [英] Exception handling, WinRT C++ concurrency async tasks

查看:162
本文介绍了异常处理,WinRT的C ++并行异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现一个异步HTTP在C ++ GET,我们必须要能够应用提交至Windows 8的商店。

I have to implement an async HTTP GET in C++ and we have to be able to submit the app to the Windows 8 Store.

我的问题是这样的:

我已经找到了合适的样品code,它实现了Htt的prequest类的 HTTP://$c$c.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664

I've found a suitable Sample code which implements an HttpRequest class http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664

此示例工作如果URI是正确的,但如果抛出URI指向一个例外,一个无效的/不存在的地方(如:www.google22.com)。这将是很好,如果我能捕捉到了异常,但我无法弄清楚如何或我应该在哪里抓住它。

This example works if the URI is correct but throws an exception if the URI points to an invalid / non existing place (like: www.google22.com). This would be fine if I could catch the exception but I cannot figure it out how or where should I catch it.

现在一些code。
这是在调用异步,并行任务::根据方法,抛出该异常:

Now some code. This is the call to the async, concurrency::task based method which throws the exception:

try {
...
Web::HttpRequest httpRequest;
    httpRequest.GetAsync(uri, cancellationTokenSource.get_token())
        .then( []  (concurrency::task<std::wstring> response)
    {
        try {
            response.get();
        }
        catch( ... ) {
            int i = 1;
        }
        return response;
    })
...
} catch ( ... ) {
...
}

和这是GetAsync方法(该方法的结束时)的相关段:

And this is the relevant segment of the GetAsync method (the end of the method):

// Return a task that completes when the HTTP operation completes. 
// We pass the callback to the continuation because the lifetime of the 
// callback must exceed the operation to ensure that cancellation 
// works correctly.
return completionTask.then([this, stringCallback](tuple<HRESULT, wstring> resultTuple)
{
    // If the GET operation failed, throw an Exception.
    CheckHResult(std::get<0>(resultTuple));

    statusCode = stringCallback->GetStatusCode();
    reasonPhrase = stringCallback->GetReasonPhrase();

    return std::get<1>(resultTuple);
});

该CheckHResult行抛出异常,这是code:

The CheckHResult line throws the exception, it's code:

inline void CheckHResult(HRESULT hResult)
{
if (hResult == E_ABORT)
{
    concurrency::cancel_current_task();
}
else if (FAILED(hResult))
{
    throw Platform::Exception::CreateException(hResult);
}
}

我周围有GetAsync调用一个try-catch我也有一个try-catch在延续。那么拉姆达。

I have a try-catch around the GetAsync call and I also have a try-catch in the .then continuation lambda.

在相关Microsoft文档(的http:// MSDN。 microsoft.com/en-us/library/windows/apps/hh780559.aspx )它指出由任务引发的异常应在链中的下一个任务开捕,但不知它不会在我的情况下工作。此外,整个待命,甚至没有在try-catch捕获该异常,它只是通过一切滑...

In the relevant Microsoft documentation ( http://msdn.microsoft.com/en-us/library/windows/apps/hh780559.aspx ) it states that exceptions thrown by a task should be catchable in the next task in the chain but somehow it doesn't work in my case. Additionally not even the try-catch around the whole call catches the exception, it just slips through everything...

任何人有这个问题?我想我已经试图在官方声明单证一切,但它仍然允许例外发狂和崩溃的应用程序。我怎么错过?

Anyone had this problem? I think I've tried everything stated in the official documentations but it still lets the exception go berserk and crash the app. What do I miss?

编辑:

我修改了code到别的什么也不要做异常处理,它仍然不赶的任务.GetAsync抛出的异常

I've modified the code to do nothing else but exception handling and it still doesn't catch the exception thrown by the task in .GetAsync

清理后的code:

try
{
  Windows::Foundation::Uri^ uri;
  uri = ref new Windows::Foundation::Uri( uri_string_to_fetch );

  concurrency::cancellation_token_source cancellationTokenSource = concurrency::cancellation_token_source();

  Web::HttpRequest httpRequest;
  OutputDebugString( L"Start to fetch the uri...\n" );
  httpRequest.GetAsync(uri, cancellationTokenSource.get_token())
    .then([](concurrency::task<std::wstring> response)
  {
    try {
      response.get();
    }
    catch( ... ) {
      OutputDebugString(L"unknown Exception");
    }
  })
  .then([](concurrency::task<void> t)
  {
    try {
      t.get();
      // .get() didn't throw, so we succeeded.
    }
    catch (Platform::Exception^ e) {
      // handle error
      OutputDebugString(L"Platform::Exception");
    }
    catch (...) {
      OutputDebugString(L"unknown Exception");
    }
  });
} 
catch (Platform::Exception^ ex) {
  OutputDebugString(L"Platform::Exception");
  errorCallback(-1);
} 
catch ( ... ) {
  OutputDebugString(L"unknown Exception");
  errorCallback(-2);
}

这仍然给我的异常消息崩溃:在0x75644B32在App1.exe第一次机会异常:微软C ++异常:平台::收到COMException ^内存位置0x077EEC28。 HRESULT:0x800C0005

This still gives me a crash with the exception message: First-chance exception at 0x75644B32 in App1.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x077EEC28. HRESULT:0x800C0005

此外,当我把一些断点在code它表明通过异常一切滑倒第一。然后将被称为前。我已经把断点在这些位置(在简化/清理code):

Additionally when I put some breakpoints in the code it shows that the exception slips through everything before the first .then would be called. I've put breakpoints in these locations (in the simplified / cleaned up code):


  • 的GetAsync调用之前

  • 进入GetAsync,到 CheckHResult(的std ::获得℃下>(resultTuple)); 线,抛出该异常

  • 到每一个尝试和catch情况/块

  • before the GetAsync call
  • into the GetAsync, to the CheckHResult(std::get<0>(resultTuple)); line which throws the exception
  • into every try and catch case / block

执行顺序,使用断点进行测试:

Order of execution, tested with breakpoints:


    在GetAsync调用之前
  1. [OK]

  2. 在GetAsync,这将引发异常的行[OK]

  3. 现在应用程序崩溃,滑过每一个的try-catch ,继续

  4. 现在,在第一次的。然后的行被调用,在它的try块

  5. 另一个应用程序级的异常没有被任何catch块逮住

  6. 现在,第一次的。然后的的catch块

  7. 第二。那么方法的的尝试的块

  8. ,仅此而已,第二的。然后的的追赶甚至没有捕获任何例外

  1. before the GetAsync call [OK]
  2. in the GetAsync, the line which will throw the exception [OK]
  3. now the app crashes, slips through every try-catch, continue
  4. now the line in the first .then gets called, in it's try block
  5. another app level exceptions not catched by any catch block
  6. now the first .then's catch block
  7. second .then method's try block
  8. and nothing more, the second .then's catch doesn't even catch any exception

和打印的调试日志,依次是:
  - 开始,以获取URI ...
  - 在0x75644B32在App1.exe第一次机会异常:微软C ++异常:平台::收到COMException ^内存位置0x082FEEF0。 HRESULT:0x800C0005
  - 在0x75644B32在App1.exe第一次机会异常:微软C ++异常:[重新抛出]在内存位置00000000。
  - 在0x75644B32在App1.exe第一次机会异常:微软C ++异常:平台::收到COMException ^内存位置0x082FE670。 HRESULT:0x800C0005
  - 在0x75644B32在App1.exe第一次机会异常:微软C ++异常:平台::收到COMException ^内存位置0x082FDD88。 HRESULT:0x800C0005
  - 未知异常

And the printed debug logs, in order: - Start to fetch the uri... - First-chance exception at 0x75644B32 in App1.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x082FEEF0. HRESULT:0x800C0005 - First-chance exception at 0x75644B32 in App1.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000. - First-chance exception at 0x75644B32 in App1.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x082FE670. HRESULT:0x800C0005 - First-chance exception at 0x75644B32 in App1.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x082FDD88. HRESULT:0x800C0005 - unknown Exception

这是怎么回事?

推荐答案

在并发运行时任何未处理的异常被推迟以后观察。通过这种方式,你可以在链的末端添加一个基于任务延续和处理错误那里。

In the Concurrency Runtime any unhandled exception that occurs during the execution of a task is deferred for later observation. In this way, you could add a task based continuation at the end of the chain and handle errors there.

事情是这样的:

httpRequest.GetAsync(uri, cancellationTokenSource.get_token())
.then([](concurrency::task<std::wstring> response)
{
    try {
        response.get();
    }
    catch( ... ) {
        int i = 1;
    }
    return response;
})
.then([](concurrency::task<void> t)
{
    try {
        t.get();
        // .get() didn't throw, so we succeeded.
    }
    catch (Platform::Exception::CreateException^ e) {
        // handle error
    }
});

。获得呼叫触发任务链(如果有的话)中提出的任何异常。
欲了解更多详细信息,你可以阅读在并发运行时 异常处理。

The call to .get triggers any exceptions that were raised in the task chain (if any). For more details you can read Exception Handling in the Concurrency Runtime.

这篇关于异常处理,WinRT的C ++并行异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆