読者です 読者をやめる 読者になる 読者になる

Officeアドインで非同期処理

C# VSTO

Officeアドイン(VSTO)を作るときは、.NetFrameworkのFull機能を使えるのでRESP API使って見たりWCF使ったりなんでもできるけど、時間のかかる処理だとやっぱりアプリが応答なしになります。

Taskクラスとか使って非同期で処理して結果をUIスレッドに戻そうとした時に
アレ?Invokeがない!?”やっぱりWindowsFormとは違った。
なかなかコレ!って日本語情報が出てこないんですよね。検索が下手なだけなのか。英語ができれば問題ないんだろうけど・・・

方法1 SynchronizationContextを使う

System.Threading.SynchronizationContext syncContext;
private void SetThreadContext()
{
  if (syncContext == null)
  {
    System.Windows.Forms.Application.DoEvents();
    if (System.Threading.SynchronizationContext.Current != null)
    {
      syncContext = System.Threading.SynchronizationContext.Current;
    }
  }
}
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
  SetThreadContext();
}
private void button1_Click(object sender, RibbonControlEventArgs e)
{
  //開始時間を設定
  label1.Label = DateTime.Now.ToString("HH:mm:ss");
  Task.Factory.StartNew(() =>
    {
      //5秒かかる重たい処理
      HeavyProcessing();
      syncContext.Send((o) =>
        {
          //終了時刻を設定
          label2.Label = DateTime.Now.ToString("HH:mm:ss");
        }, null);
    });
}

方法2 async/awaitを使う

方法1をやってたあとに、”.net4.5が使えるならasync/awaitいけるんじゃね?”
行けた。

private async void button2_Click(object sender, RibbonControlEventArgs e)
{
  //開始時間を設定
  label1.Label = DateTime.Now.ToString("HH:mm:ss");
  await HeavyProcessingAsync();
  //終了時刻を設定
  label2.Label = DateTime.Now.ToString("HH:mm:ss");
}


(∩´∀`)∩ワーイ
もちょっとThreatとか勉強しよう。