2

如何在 windows phone 8、c++/cx 上捕获 I/O 异常?

编辑:这是一个完整的例子

检查文件“hello.txt”是否存在:

StorageFile^ Testme(String^ fileName)
{
    StorageFolder^ item =  ApplicationData::Current->LocalFolder; 
    try
    { 
        task<StorageFile^> getFileTask(item->GetFileAsync("hello.txt")); 
        getFileTask.then([](StorageFile^ storageFile)
        { 
           return storageFile;
         }); 
     }
     catch (Exception^ ex)
     {
        OutputDebugString(L"Caught the exception");
     }
     return nullptr;
}

如果“hello.txt”存在,Testme 方法会像魅力一样返回文件 ptr。
如果“hello.txt 不存在,它不仅不会抛出异常 FileNOtFound,而是在调试器窗口中显示此内容而崩溃:

MyPhoneApp.exe 中 0x71D49C01 (Msvcr110d.dll) 处的未处理异常:传递了无效参数到一个认为无效参数致命的函数。如果有这个异常的处理程序,程序可以安全地继续有

什么问题,我将如何优雅地检查文件是否存在于 WP8 中?

我真的希望有人回答......谢谢.

4

1 回答 1

2

在花了几个小时找出相关问题中的问题后,我终于弄明白了。使用 C++,看起来 Visual Studio 的行为有点有趣。它没有将异常传递给用户,而是抛出它。这意味着即使您有异常处理程序,也不允许您的处理程序处理它。我应该在这里指出,这只发生在您在 Visual Studio 中运行您的应用程序时。部署和启动应用程序显示没有问题。

因此,要解决它,请打开异常设置(从菜单 > 调试 > 异常 - 或 Ctrl+D、E)。放大“C++ Exceptions”并取消选择“Thrown”列中的“Platform::InvalidArgumentException”。那么你应该很高兴。

第一条评论后更新:

首先,我也必须从列表中取消选择 COMException 才能使下面的示例正常工作。

除了上面做的。了解 C++/CX 中的异步编程很重要。创建任务后,您不能简单地从函数返回。如果你真的需要返回,你需要返回你创建的工作任务来完成这项工作。下面是一个 Windows 应用商店应用示例(不是 WP),但它们的工作方式应该相同。您的辅助函数必须如下所示。

concurrency::task<bool> TestFileExists::MainPage::Testme(String^ fileName)
{
    using namespace Windows::Storage;
    using namespace concurrency;

    StorageFolder^ item =  ApplicationData::Current->LocalFolder; 

    return create_task(item->GetFileAsync(fileName)).then([this](task<StorageFile^> t)
    {
            bool fileExists = true;

            try {
                    StorageFile^ file = t.get();
            }
            catch(Platform::Exception^ exp)
            {
                    fileExists = false;
            }

            return (fileExists);
    });
}

你应该像下面这样称呼它。

Testme("hello.txt").then([this](concurrency::task<bool> t)
{
    auto dispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;

    // dispatch the task of updating the UI to the UI task not to run into exception
    dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
        ref new Windows::UI::Core::DispatchedHandler(
        [=]()
    {
        bool exists = t.get();

        if (exists)
        {
            txtbFileExists->Text = L"File is there";
        }
        else
        {
            txtbFileExists->Text = L"File is NOT there";
        }

    }));

});

我不知道本地文件夹在哪里,所以我无法测试文件实际存在的条件。请测试并查看。

于 2013-02-03T15:48:13.230 回答