Как отловить исключения, генерируемые методом ConnectAsync в MessageWebSocket? - PullRequest
0 голосов
/ 27 октября 2019

Я реализую приложение UWP для HoloLens, которое передает облако точек через MessageWebSocket на компьютер-компаньон. Если я запускаю приложение на HoloLens, когда сервер на компьютере-компаньоне еще не запущен, вызов метода ConnectAsync для MessageWebSocket вызывает исключение (потому что оно не может подключиться к серверу), которое вызывает сбой моего приложения,Однако я не могу понять, как перехватить это исключение.

Вдохновленный примером кода, приведенным в официальной документации MessageWebSocket , это небольшой пример, который воспроизводит проблему:

void TryConnectToWebsocket()
{
    Windows::Networking::Sockets::MessageWebSocket^ websocket = ref new Windows::Networking::Sockets::MessageWebSocket();
    websocket->Control->MessageType = Windows::Networking::Sockets::SocketMessageType::Utf8;

    try
    {
        ::OutputDebugString(L"Trying to connect...\n");
        auto connectTask = Concurrency::create_task(websocket->ConnectAsync(ref new Windows::Foundation::Uri(L"ws://192.168.0.38:9090")));
        connectTask.then([this, websocket]
        {
            ::OutputDebugString(L"Connected successfully!");
            websocket->Close(1000, "Application caused the connection to close.");
        });
    }
    catch (...)
    {
        ::OutputDebugString(L"Couldn't connect to websocket!");
    }
}

Обратите внимание, что исходный пример кода из документов перехватывает исключения типа Platform::Exception. Я решил перехватывать исключения всех типов в этом фрагменте кода, чтобы утверждать, что я не пропущу исключение в случае, если оно не является Platform::Exception (или его подтипом).

Если я запускаю этот кодфрагмент (без запуска сервера), я ожидал бы следующий вывод консоли:

Trying to connect...
Couldn't connect to the websocket!

Тем не менее, я получаю следующее: (Выводы консоли о загруженных и выгруженных DLL были пропущены. Некоторые изсообщения о том, что пошло не так, изначально были на немецком языке, поэтому я перевел их.)

Trying to connect...
Exception thrown at 0x76B34592 (KernelBase.dll) in Test.exe: WinRT originate error - 0x80072EFD : 'A connection with the server could not be established.'.
Exception thrown at 0x76B34592 in Test.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x0C5AE500. HRESULT:0x80072EFD The message for this error code could not be found.
WinRT information: A connection with the server could not be established.
Stack trace:
 >[External Code]

Как видите, блок catch вообще не выполняется. Кроме того, из-за очень короткой и неточной трассировки стека создается впечатление, что исключение выдается где-то в фоновом потоке, где у меня даже нет шансов его перехватить.

Мне бы очень хотелось обработать это исключение, вместо того, чтобы вызывать сбой приложения. Есть ли способ, как я могу это сделать?

1 Ответ

1 голос
/ 30 октября 2019

Из официального образца он не помещает все операции, которые могут быть выполнены, в блок try ... catch. Вместо этого он добавляет продолжение на основе задач в конце цепочки и обрабатывает там все ошибки. Вы можете попробовать следующий код, чтобы поймать исключение.

create_task(messageWebSocket->ConnectAsync(ref new Windows::Foundation::Uri(L"ws://192.168.0.38:9090")))
        .then([this](task<void> previousTask)
            {
                try
                {
                    previousTask.get();
                    ::OutputDebugString(L"Connected successfully!");
                    websocket->Close(1000, "Application caused the connection to close.");
                }
                catch (Exception^ ex)
                {
                    ::OutputDebugString(L"Couldn't connect to websocket!");
                }

            });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...