You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VSTO Outlook插件内使用WebView2控件时的异步代码问题

解决方案:Outlook VSTO Send事件中同步调用WebView2 ExecuteScriptAsync方法

核心问题原因

  • Outlook的ItemEvents_10_SendEventHandler是同步回调,ref参数Cancel必须在回调返回前完成赋值,无法在异步上下文中操作
  • WebView2的CoreWebView2所有接口仅能在创建它的UI线程执行,直接跨线程调用就会抛出CoreWebView2 can only be accessed from the UI thread.错误
  • 直接使用.Wait()、.Result同步等待异步方法,会因为UI线程上下文阻塞触发死锁

可行实现方案

实现原理:提前缓存UI线程调度器,将WebView2异步操作封送到UI线程执行,同时通过消息泵送避免同步等待导致的死锁。

  1. 首先在WebView2所在的窗体/用户控件初始化阶段,缓存当前UI线程的Dispatcher:
// 提前声明全局变量
private Dispatcher _uiDispatcher = Dispatcher.CurrentDispatcher;
  1. Send事件处理逻辑如下:
private void ItemEvents_10_SendEventHandler(ref bool Cancel)
{
    bool isScriptExecuted = false;
    string jsExecutionResult = string.Empty;

    // 将WebView2操作封送到UI线程执行
    _uiDispatcher.Invoke(async () =>
    {
        try
        {
            // 替换为你需要执行的JS脚本
            jsExecutionResult = await webView2Control.CoreWebView2.ExecuteScriptAsync("yourCustomJSFunction()");
        }
        catch (Exception ex)
        {
            // 自定义异常处理逻辑,例如日志打印
            System.Diagnostics.Debug.WriteLine($"JS执行异常: {ex.Message}");
        }
        finally
        {
            isScriptExecuted = true;
        }
    }, System.Windows.Threading.DispatcherPriority.Normal);

    // 同步等待异步结果,同时泵送消息避免死锁
    while (!isScriptExecuted)
    {
        System.Windows.Forms.Application.DoEvents();
        // 降低循环CPU占用
        System.Threading.Thread.Sleep(10);
    }

    // 根据JS返回结果设置Cancel值,以下为示例逻辑,可按需修改
    if (jsExecutionResult.Trim('"') == "cancelSend")
    {
        Cancel = true;
    }
}

注意事项

  • 必须等待WebView2的CoreWebView2InitializationCompleted事件触发完成后再执行上述逻辑,避免CoreWebView2为空报错
  • 可按需添加超时判断逻辑,例如等待超过3秒就强制终止等待、设置Cancel为true,避免JS执行异常导致Outlook长时间无响应
  • 本方案兼容你当前使用的WebView2 1.0.1020.30、VS2019、Outlook PIA 15环境,无需升级依赖

内容的提问来源于stack exchange,提问作者TomoP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:24:10