Windows runtime 为什么CreateFileAsync()继续未执行?

Windows runtime 为什么CreateFileAsync()继续未执行?,windows-runtime,c++-cx,Windows Runtime,C++ Cx,在下面的代码中,CreateFileAsync()的延续既不打印也不访问pdone。但是,将创建长度为零的文件Hello.txt auto pdone = make_shared<bool>(false); create_task(folderLocal->CreateFileAsync("Hello.txt", CreationCollisionOption::ReplaceExisting)).then([pdone](StorageFile ^file) { O

在下面的代码中,
CreateFileAsync()
的延续既不打印也不访问
pdone
。但是,将创建长度为零的文件Hello.txt

auto pdone = make_shared<bool>(false);

create_task(folderLocal->CreateFileAsync("Hello.txt", CreationCollisionOption::ReplaceExisting)).then([pdone](StorageFile ^file) {
    OutputDebugString(L"In CreateFileAsync continuation!\n");
    *pdone = true;
});

create_task([pdone]{
    OutputDebugString(L"In my task!\n");
});

create_async([pdone]{
    OutputDebugString(L"In my async!\n");
});

while (!*pdone) {}
OutputDebugString(L"Done!\n");
我还不太熟悉WinRT线程的调试,但我没有看到任何明显的异常,也没有看到任何不应该执行异步操作的继续的原因。目标平台是全息透镜模拟器

任何想法都很感激。
谢谢 如果您必须这样做(尽管您确实应该尝试并避免这样做),您需要使用“continuation context”来告诉PPL在其他地方运行continuation

这里有一个例子。首先,基本XAML(只粘贴在一个空白的C++ xAML项目的<代码>网格>代码>下:


如前所述,您不应该这样做。如果需要同步文件I/O,并且要访问自己包中的文件,请使用Win32 API
CreateFile2
。如果您需要访问包外的文件(例如,从文件选择器或照片库),则应使用完全异步的编程方法。

我认为使用task\u continuation\u context::use\u arbitarty()是正确的方法,不过,我认为微软建议使用稍有不同的方式,除非我误解了这个链接(一直滚动到底):


我不会为StorageFile API操心——它的使用速度非常慢,而且非常笨拙。只需使用CreateFile2即可。当您旋转时,线程很忙,因此无法继续运行。我对C++/CX不是很熟悉,但我相信如果此代码位于事件处理程序中,则需要从中返回。后续将在稍后运行。
In my task!
In my async!
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button Content="Hang the UI thread" Click="Hang"/>
    <Button Content="Do not do this" Click="DoNotDoThis"/>
</StackPanel>
using namespace Windows::Storage;
using namespace concurrency;

void DoIt(task_continuation_context& context)
{
  auto folder = ApplicationData::Current->LocalFolder;
  auto done = std::make_shared<bool>(false);
  create_task(folder->CreateFileAsync(L"x", CreationCollisionOption::ReplaceExisting))
  .then([done](StorageFile^ file) mutable
  {
    OutputDebugString(L"Done creating file\n");
    *done = true;
  }, context);

  OutputDebugString(L"Going to wait... DO NOT DO THIS IN PRODUCTION CODE!\n");
  while (!*done)
    ;

  OutputDebugString(L"Done waiting\n");
}

void MainPage::Hang(Platform::Object^ sender, RoutedEventArgs^ e)
{
  OutputDebugString(L"Starting Hang\n");
  // The default context == the UI thread (if called from UI)
  DoIt(task_continuation_context::use_default());
  OutputDebugString(L"Ending Hang\n");
}

void MainPage::DoNotDoThis(Platform::Object^ sender, RoutedEventArgs^ e)
{
  OutputDebugString(L"Starting DoNotDoThis\n");
  // An arbitrary context will pick another thread (not the UI)
  DoIt(task_continuation_context::use_arbitrary());
  OutputDebugString(L"Ending DoNotDoThis\n");
}
create_task(folderLocal->CreateFileAsync("Hello.txt", CreationCollisionOption::ReplaceExisting)).then([pdone](StorageFile ^file) {
    OutputDebugString(L"In CreateFileAsync continuation!\n");
    *pdone = true;
}, task_continuation_context::use_arbitrary());