StorageFile 的 IVectorView 在循环中 OpenReadAsync 后变为 null(可能是 winrt 错误)

IVectorView of StorageFile becomes null after OpenReadAsync in a loop (possible winrt bug)

我正在 BlankApp 项目模板中创建一个运行时 class,它打开一个 IVectorView<StorageFile>,它通过引用作为参数接收。然后它循环遍历向量以从文件中读取。但是,当我在读取调用后尝试使用向量时,它会引发读取访问冲突。

我之所以认为这是一个错误,是因为它只在我使用 BlankApp 项目的 x64 配置进行编译时发生。在 x86 中不会抛出异常。

这很容易重现,所以如果其他人可以确认他们是否发生过这种情况,那就太好了。

//test_class.idl

[bindable]
[default_interface]
runtimeclass test_class
{
    test_class();

    Windows.Foundation.IAsyncAction read_files(Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFile> files);
}
//test_class.cpp
Windows::Foundation::IAsyncAction test_class::read_files(Windows::Foundation::Collections::IVectorView<Windows::Storage::StorageFile> const& files)
{
    for (auto& file : files)
    {
        auto res = files;
        auto stream = co_await file.OpenReadAsync();
        auto res2 = files; // read access violation. this->**m_ptr** was 0xFFFFFFFFFFFFFFFF.
    }

    co_return;
}
//MainPage.cpp
Windows::Foundation::IAsyncAction MainPage::onclick_button(Windows::Foundation::IInspectable const & sender, Windows::UI::Xaml::RoutedEventArgs const & args)
{
    BlankApp1::test_class m_test_class = winrt::make<BlankApp1::implementation::test_class>();

    Windows::Storage::Pickers::FileOpenPicker picker;
    picker.FileTypeFilter().Append(L".bmp");

    Windows::Foundation::Collections::IVectorView<Windows::Storage::StorageFile> files = co_await picker.PickMultipleFilesAsync();

    co_await m_test_class.read_files(files);
}

发生这种情况是因为您通过引用异步方法传递了一个 arg。在 co_await 期间,调用函数 (onclick_button) 可能已经清理了您的引用所引用的对象,基本上导致了悬空引用。为避免这种情况,您的协同程序应按值而不是按引用接受参数。

有关详细信息,请参阅以下部分: https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/concurrency#parameter-passing