create_async 在 UI 线程上的表现如何?

How does create_async behave on the UI thread?

假设我有一个在 UI 线程上调用的函数:

IAsyncOperation<BitmapImage^>^ GetImage()
{
    return create_async([]
    {
        return create_task(GetStreamAsync())
            .then([] (Stream^ stream)
        {
            auto image = ref new BitmapImage();
            // set image properties.
            image.SetSourceAsync(stream);
            return image;
        });
    });
}

我知道内部任务也将在 UI 线程上执行,因为 指示单元感知任务默认在其单元中继续。

但是 create_task 主体的执行时间是什么时候?它最终会同步发生吗?还是 UI 线程等待直到它有空闲周期来处理异步逻辑?

让我们找出答案:

void ShowThread(std::string caller)
{
  std::string result{ caller + ": Current thread is " };
  result = result + std::to_string(GetCurrentThreadId());
  result = result + "\r\n";

  OutputDebugStringA(result.c_str());
}

using namespace Windows::Foundation;
using namespace Windows::Storage;

IAsyncOperation<IStorageItem^>^ GetFile()
{
  ShowThread("GetFile");
  return create_async([]
  {
    ShowThread("Inside create_async");
    return create_task(
      ApplicationData::Current->LocalFolder->TryGetItemAsync(L"foo"))
      .then([](IStorageItem^ item)
      {
        ShowThread("Inside .then");
        return item;
    });
  });
}

MainPage::MainPage()
{
  InitializeComponent();
  GetFile();
}

显示如下:

GetFile: Current thread is 34100
Inside create_async: Current thread is 34100
Inside .then: Current thread is 34100

您可以看到它们都在同一个线程上 - create_async 立即调用它的参数(它不会将其安排为任务)并简单地将 return 值转换为 IAsyncOperation<T>。如果您希望 而不是 的延续在 UI 线程上,您可以这样做:

    return create_task(
      ApplicationData::Current->LocalFolder->TryGetItemAsync(L"foo"))
      .then([](IStorageItem^ item)
    {
      ShowThread("Inside .then");
      return item;
    }, task_continuation_context::use_arbitrary());

然后 PPL 将 运行 在任意线程上继续。