Проблема с асинхронным кодом при использовании элемента управления WebView2 внутри плагина VSTO Outlook

#c# #async-await #vsto #webview2

Вопрос:

Я хочу использовать новейший элемент управления Microsoft WebView2 (Chromium) в плагине VSTO для Outlook. У меня возникли проблемы с подключением асинхронного интерфейса WebView2 с VSTO Outlook.Инспектор и перспективы.ItemEvents_10_Event, например, Отправить или Закрыть.

Я хочу выполнить некоторый сценарий JS на WebView2 для этих событий, вызвав ExecuteScriptAsync из элемента управления WebView2.

Проблема в том, что, например, событие отправки объявляется как void ItemEvents_10_SendEventHandler(ref bool Cancel) Проблема с переменной ref в том, что ее нельзя использовать для асинхронности.

Мне нужно включить этот асинхронный код в синхронизацию, чтобы определить результат для отмены ссылки, но я понятия не имею об этом. Я заканчиваю с тупиком или ошибкой из элемента управления WebView2 CoreWebView2 can only be accessed from the UI thread.

Настройка VS2019, Outlook PIA 15 и WebView2 1.0.1020.30

Комментарии:

1. Покажите больше кода, чтобы нам было с чем «работать» вместо простого описания вашего кода.

Ответ №1:

В обработчике событий запустите цикл сообщений Windows, ожидая возвращения асинхронного метода

 MSG msg;  while (PeekMessage(out msg, IntPtr.Zero, 0, 0, 1/*PM_REMOVE*/))  {   TranslateMessage(ref msg);  DispatchMessage(ref msg);  if (OnlyOnce) break;  }  

Функции Win API определены ниже:

 [StructLayout(LayoutKind.Sequential)]  public struct POINT  {  public int X;  public int Y;  }   [StructLayout(LayoutKind.Sequential)]  public struct MSG  {  public IntPtr hwnd;  public uint message;  public UIntPtr wParam;  public IntPtr lParam;  public int time;  public POINT pt;  public int lPrivate;  }  [DllImport("user32.dll")]  static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);  [DllImport("user32.dll")]  static extern bool TranslateMessage([In] ref MSG lpMsg);  [DllImport("user32.dll")]  static extern IntPtr DispatchMessage([In] ref MSG lpmsg);  [DllImport("user32.dll")]  [return: MarshalAs(UnmanagedType.Bool)]  static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);  

Комментарии:

1. Спасибо за идею!