代码之家  ›  专栏  ›  技术社区  ›  Craig

create\u async在UI线程上的行为如何?

  •  1
  • Craig  · 技术社区  · 6 年前

    假设我有一个在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线程上执行,因为 this question's answer 表示默认情况下,单元感知任务在其单元中继续。

    但是,create\u任务体的执行计划在何时执行?它最终会同步发生吗?或者UI线程会等到有空闲周期时再处理异步逻辑吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Peter Torr    6 年前

    让我们看看:

    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 立即调用其参数(它不会将其计划为任务),并将返回值转换为 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将在任意线程上运行continuation。

    推荐文章