问题描述
我要实现一个异步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类的
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文档()它指出由任务引发的异常应在链中的下一个任务开捕,但不知它不会在我的情况下工作。此外,整个待命,甚至没有在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:
- [OK]
- 在GetAsync,这将引发异常的行[OK]
- 现在应用程序崩溃,滑过每一个的try-catch ,继续
- 现在,在第一次的。然后的行被调用,在它的try块
- 另一个应用程序级的异常没有被任何catch块逮住
- 现在,第一次的。然后的的catch块
- 第二。那么方法的的尝试的块
- ,仅此而已,第二的。然后的的追赶甚至没有捕获任何例外
在GetAsync调用之前
- before the GetAsync call [OK]
- in the GetAsync, the line which will throw the exception [OK]
- now the app crashes, slips through every try-catch, continue
- now the line in the first .then gets called, in it's try block
- another app level exceptions not catched by any catch block
- now the first .then's catch block
- second .then method's try block
- 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
}
});
到。获得
呼叫触发任务链(如果有的话)中提出的任何异常。
欲了解更多详细信息,你可以阅读在并发运行时 异常处理。
这篇关于异常处理,WinRT的C ++并行异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!