Help us understand the problem. What is going on with this article?

STAで実行されるTaskの生成

More than 5 years have passed since last update.

C# の async/await を利用した非同期処理はお手軽で良いけれど、XPSDocument なんかをいじってると、Task.Run() で返される Task オブジェクトが MTA なため時々実行できませんと怒られてしまう。そういう場合、STA で実行される Task オブジェクトを生成してやると回避できる場合がある。

そこで見よう見まねで、Task.Run() ぽい感じで使える、STA で実行されるスレッドを生成する Task オブジェクトを返すクラス STATask を書いてみた。

statask.cs
// STAで実行されるTaskオブジェクトを生成する
class STATask
{
  public static Task Run<T>(Func<T> func)
  {
    var tcs = new TaskCompletionSource<T>();
    var thread = new Thread(() =>
    {
      try
      {
        tcs.SetResult(func());
      }
      catch (Exception e)
      {
        tcs.SetException(e);
      }
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    return tcs.Task;
  }

  public static Task Run(Action act)
  {
    return Run(() =>
    {
      act();
      return true;
    });
  }
}

以下のような感じで使うことができる。

sample.cs
private async void foo()
{
  await STATask.Run(() =>
  {
    // 非同期実行したい処理
    Thread.Sleep(1000);
  });
}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away