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 に答える