LoginSignup
25
26

More than 5 years have passed since last update.

STAで実行されるTaskの生成

Posted at

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);
  });
}

25
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
26