Manejo de excepciones, tareas asíncronas de concurrencia de WinRT C ++

Tengo que implementar un HTTP GET asíncrono en C ++ y debemos poder enviar la aplicación a la Tienda de Windows 8.

Mi problema es el siguiente:

He encontrado un código de muestra adecuado que implementa una clase HttpRequesthttp://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664

Este ejemplo funciona si el URI es correcto, pero lanza una excepción si el URI apunta a un lugar no válido / no existente (como: www.google22.com). Esto estaría bien si pudiera detectar la excepción, pero no puedo entender cómo o dónde debería capturarla.

Ahora algo de código. Esta es la llamada al método basado en async, concurrency :: task que lanza la excepción:

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 ( ... ) {
...
}

Y este es el segmento relevante del método GetAsync (el final del método):

// 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);
});

La línea CheckHResult lanza la excepción, es el código:

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

Tengo un try-catch alrededor de la llamada GetAsync y también tengo un try-catch en el .then continuación lambda.

En la documentación pertinente de Microsoft (http://msdn.microsoft.com/en-us/library/windows/apps/hh780559.aspx ) indica que las excepciones lanzadas por una tarea deberían poder detectarse en la siguiente tarea de la cadena, pero de alguna manera no funciona en mi caso. Además, ni siquiera el try-catch en toda la llamada atrapa la excepción, simplemente se desliza a través de todo ...

Alguien ha tenido este problema? Creo que he intentado todo lo que se indica en las documentaciones oficiales, pero todavía permite que la excepción se vuelva loca y bloquee la aplicación. ¿Qué me pierdo?

EDITAR:

He modificado el código para que no haga nada más que el manejo de excepciones y todavía no detecta la excepción lanzada por la tarea en .GetAsync

Código de limpieza:

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);
}

Esto todavía me da un crash con el mensaje de excepción:Excepción de primera oportunidad en 0x75644B32 en App1.exe: excepción de Microsoft C ++: Platform :: COMException ^ en la ubicación de memoria 0x077EEC28. HRESULT: 0x800C0005

Además, cuando coloco algunos puntos de interrupción en el código, muestra que la excepción se desliza a través de todo antes de que se llame al primer .then. He puesto puntos de interrupción en estas ubicaciones (en el código simplificado / limpiado):

antes de la llamada GetAsyncen el GetAsync, a laCheckHResult (std :: get <0> (resultTuple)); línea que lanza la excepciónen cada intento / captura de caso / bloque

Orden de ejecución, probado con puntos de interrupción:

antes de la llamada GetAsync [OK]en el GetAsync, la línea que lanzará la excepción [OK]ahora la aplicación falla, se desliza a través de cada try-catchcontinuarahora la linea en la primera.entonces se llama, en su bloque de pruebaOtras excepciones de nivel de aplicación no son atrapadas por ningún bloque catchahora el primero.entoncesbloque de capturasegundo. luego métodotratar bloquearY nada más, el segundo..entoncesLa captura ni siquiera atrapa ninguna excepción.

Y los registros de depuración impresos, en orden: - Comience a buscar la uri ... - Excepción de primera oportunidad en 0x75644B32 en App1.exe: excepción de Microsoft C ++: Platform :: COMException ^ en la ubicación de memoria 0x082FEEF0. HRESULT: 0x800C0005 - Excepción de primera oportunidad en 0x75644B32 en App1.exe: Excepción de Microsoft C ++: [rethrow] en la ubicación de memoria 0x00000000. - Excepción de primera oportunidad en 0x75644B32 en App1.exe: excepción de Microsoft C ++: Platform :: COMException ^ en la ubicación de memoria 0x082FE670. HRESULT: 0x800C0005 - Excepción de primera oportunidad en 0x75644B32 en App1.exe: Excepción de Microsoft C ++: Plataforma :: COMException ^ en la ubicación de memoria 0x082FDD88. HRESULT: 0x800C0005 - Excepción desconocida

¿¿Que esta pasando??

Respuestas a la pregunta(2)

Su respuesta a la pregunta