Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何捕获MessageWebSocket的ConnectAsync方法引发的异常?_C++_Websocket_Uwp - Fatal编程技术网

C++ 如何捕获MessageWebSocket的ConnectAsync方法引发的异常?

C++ 如何捕获MessageWebSocket的ConnectAsync方法引发的异常?,c++,websocket,uwp,C++,Websocket,Uwp,我正在为HoloLens实现一个UWP应用程序,该应用程序通过MessageWebSocket将点云传输到同伴电脑。如果我在同伴电脑上的服务器尚未运行时在HoloLens上启动应用程序,调用MessageWebSocket的ConnectAsync方法会触发异常(因为它无法连接到服务器)这会导致我的应用程序崩溃。但是,我不知道如何捕获此异常 create_task(messageWebSocket->ConnectAsync(ref new Windows::Foundation::Uri

我正在为HoloLens实现一个UWP应用程序,该应用程序通过
MessageWebSocket
将点云传输到同伴电脑。如果我在同伴电脑上的服务器尚未运行时在HoloLens上启动应用程序,调用
MessageWebSocket
ConnectAsync
方法会触发异常(因为它无法连接到服务器)这会导致我的应用程序崩溃。但是,我不知道如何捕获此异常

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

            });
受中所示示例代码的启发,这是一个小示例,再现了该问题:

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
(或其子类型),我不会错过该异常

如果我运行此代码段(不启动服务器),我将期望以下控制台输出:

正在尝试连接。。。
无法连接到websocket!
然而,我得到的是以下信息:(关于加载和卸载DLL的控制台输出被省略了。一些描述出错原因的消息最初是德语的,所以我翻译了它们。)

正在尝试连接。。。
Test.exe中0x76B34592(KernelBase.dll)处引发异常:WinRT原始错误-0x80072EFD:“无法建立与服务器的连接。”。
Test.EXE中的0x76B345 92抛出异常:微软C++异常:平台::在内存位置0x0C5AE500。
WinRT信息:无法建立与服务器的连接。
堆栈跟踪:
>[外部代码]
正如您所看到的,catch块根本没有被执行。此外,非常短且不精确的堆栈跟踪使它看起来好像异常是在后台线程的某个地方抛出的,而我甚至没有机会捕获它

我真的希望处理此异常,而不是让应用程序崩溃。有什么方法可以做到这一点吗?

从中,它不会将可能抛出的每个操作都放在try…catch块中。相反,它会在链的末尾添加一个基于任务的延续,并在那里处理所有错误。您可以在catc中尝试以下代码h例外

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

            });
create_任务(messageWebSocket->ConnectAsync(参考新的Windows::Foundation::Uri(L“ws://192.168.0.38:9090”))
.然后([此](任务上一个任务)
{
尝试
{
previousTask.get();
::OutputDebugString(L“已成功连接!”);
websocket->Close(1000,“应用程序导致连接关闭”);
}
捕获(异常^ex)
{
::OutputDebugString(L“无法连接到websocket!”);
}
});

通过测试,我可以重现这个问题,但除了错误,我还跳过了“没有加载符号”页面,你有相同的行为吗?@Faywang MSFT我添加了Microsoft符号服务器作为Visual Studio中调试的符号文件位置(可以在工具->选项->调试->符号中完成)。因此,我看不到这一点“未加载符号”页面。这解决了问题。非常感谢您的帮助:)