如何冻结VSTO上的Outlook窗口?

时间:2017-06-30 08:58:10

标签: c# outlook vsto outlook-addin office-addins

我有MessageBox对话框的问题,通常,MessageBox会冻结并阻止窗口,并显示在当前窗口的顶部,直到用户单击消息框按钮,但我得到的消息框无法阻止并冻结 VSTO 功能区按钮

上的当前窗口
private async void BtnTest_Click(object sender, RibbonControlEventArgs e)
{
    MessageBox.Show("before");

    var task = await DoSomethingAsync();

    MessageBox.Show("after");
}

private async Task<bool> DoSomethingAsync()
{
    await Task.Delay(1000);
    return true;
}

第一个MessageBox可以冻结窗口,但第二个不能没有,经过调查我发现它是由等待引起的,当我等待DoSomethingAsync完成时,第二个MessageBox通常会冻结并阻止当前的窗口

private void BtnTest_Click(object sender, RibbonControlEventArgs e)
{
    MessageBox.Show("before");

    var task = DoSomethingAsync();
    task.Wait();
    var result = task.Result;

    MessageBox.Show("after");
}

但我不想阻止Office Outlook Robbin UI,所以我想执行DoSomethingAsync异步,任何人都知道如何修复它?

1 个答案:

答案 0 :(得分:0)

您可以使用Thread.Start方法运行辅助线程:

using System.Threading;

Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
thread.Start();

WorkThreadFunction方法应如下所示:

public void WorkThreadFunction()
{
  try
  {
     // do any background work
  }
  catch (Exception ex)
  {
     // log errors
  }
}

另外,我建议为Show方法指定父窗口句柄。您可以将Inspector或Explorer类的实例强制转换为IOleWindow接口,该接口提供GetWindow函数,该函数检索参与就地激活的其中一个窗口的句柄。

然后你可以创建一个IWin32Window接口的实例,它可以传递给Show方法:

public class WindowWrapper : System.Windows.Forms.IWin32Window
{
   public WindowWrapper(IntPtr handle)
   {
       _hwnd = handle;
   }

   public IntPtr Handle
   {
       get { return _hwnd; }
   }

   private IntPtr _hwnd;
 }