You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为UWP并发文件追加代码添加异常处理?

处理C++/CX异步文件操作中的异常

我太懂这种挫败感了——C++/CX里的异步任务异常处理和普通同步代码完全不是一回事,你直接在外层套try-catch根本抓不到异步任务里蹦出来的异常,因为这些异常会被封装到task对象里,得用正确的姿势去捕获才行。

下面给你两种靠谱的处理方案,你可以根据需求选:

方案一:在任务延续中统一捕获异常

这种方法会捕获任务链中所有环节的异常(比如文件找不到、损坏、权限不够等),核心是用带task<void>参数的延续,然后调用get()触发异常抛出:

StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->GetFileAsync(txtfile))
    // 先执行文件追加的任务,把它返回给下一个延续
    .then([](StorageFile^ sampleFile) {
        return concurrency::create_task(FileIO::AppendTextAsync(sampleFile, New_Program_Data));
    })
    // 用task<void>接收上一个任务,在这里处理异常
    .then([](concurrency::task<void> previousTask) {
        try {
            previousTask.get(); // 这一步会抛出之前任务链里的所有未处理异常
        } catch (Platform::Exception^ ex) {
            // 这里可以根据错误类型做不同处理
            OutputDebugString(ex->Message->Data());
            
            // 举个例子:如果是文件不存在,就创建后重试
            if (ex->HResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
                auto folder = ApplicationData::Current->LocalFolder;
                concurrency::create_task(folder->CreateFileAsync(txtfile, CreationCollisionOption::OpenIfExists))
                    .then([](StorageFile^ newFile) {
                        concurrency::create_task(FileIO::AppendTextAsync(newFile, New_Program_Data));
                    });
            }
            // 还可以处理其他错误,比如权限不足、文件损坏等
            else if (ex->HResult == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) {
                // 处理权限问题的逻辑
            }
        }
    });

方案二:提前检查文件状态,主动避免异常

如果不想靠异常处理来应对文件不存在的情况,可以先用TryGetItemAsync检查文件是否存在,它不会在文件不存在时抛出异常,而是返回nullptr,这样你能主动分支处理:

StorageFolder^ storageFolder = ApplicationData::Current->LocalFolder;
concurrency::create_task(storageFolder->TryGetItemAsync(txtfile))
    .then([](IStorageItem^ item) {
        if (item != nullptr && item->IsOfType(StorageItemTypes::File)) {
            // 文件存在,直接追加数据
            return concurrency::create_task(FileIO::AppendTextAsync(static_cast<StorageFile^>(item), New_Program_Data));
        } else {
            // 文件不存在,创建后再追加
            auto folder = ApplicationData::Current->LocalFolder;
            return concurrency::create_task(folder->CreateFileAsync(txtfile, CreationCollisionOption::OpenIfExists))
                .then([](StorageFile^ newFile) {
                    return concurrency::create_task(FileIO::AppendTextAsync(newFile, New_Program_Data));
                });
        }
    })
    // 最后还是要加个异常处理,应对其他意外情况(比如文件损坏、权限问题)
    .then([](concurrency::task<void> previousTask) {
        try {
            previousTask.get();
        } catch (Platform::Exception^ ex) {
            OutputDebugString(ex->Message->Data());
        }
    });

几个关键注意点:

  • 绝对不要在UI线程直接调用task::get(),这会阻塞UI,导致界面卡顿甚至无响应,一定要放在异步延续里处理。
  • Platform::Exception^里的HResult是判断错误类型的关键,常见的错误码可以参考Windows API的定义,比如ERROR_FILE_NOT_FOUND对应文件不存在,ERROR_ACCESS_DENIED对应权限不足。

内容的提问来源于stack exchange,提问作者Gavin Hannah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:54:17