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

Win32与UWP互通信时SendMessageAsync随机抛出异常问题

解决UWP中WinForms组件调用SendMessageAsync时的InvalidOperationException问题

我之前也踩过类似的坑,结合你的场景给你几个针对性的解决方向:

1. 换掉async void的写法(事件处理除外)

你当前的SendToUWPVoidAsync用了async void,这种写法除了UI事件处理程序外,很容易导致上下文混乱、异常无法被捕获,甚至触发意外的线程切换。改成async Task会更可控:

private async Task SendToUWPAsync(object content)
{
    ValueSet message = new ValueSet();
    // 你的message填充逻辑...

    // 先检查连接状态再发送
    if (connection?.Status == AppServiceConnectionStatus.Connected)
    {
        try
        {
            var response = await connection.SendMessageAsync(message);
            // 这里可以处理UWP返回的响应
        }
        catch (Exception ex)
        {
            // 主动捕获异常,避免程序崩溃
        }
    }
    else
    {
        // 连接未就绪,可做重试提示或延迟处理
    }
}

调用时如果是在事件里,直接用await SendToUWPAsync(content);;非事件场景要确保正确处理异步流程。

2. 等AppServiceConnection完全建立后再发消息

启动WinForms组件时,很可能AppService的连接还没完成Connected状态切换,这时候调用SendMessageAsync就会触发异常。你可以这么做:

  • 监听connection.StatusChanged事件,维护一个连接就绪的标记
  • 发送消息前必须检查connection.Status是否为AppServiceConnectionStatus.Connected
  • 如果是启动WinForms后立即发消息,用TaskCompletionSource等待连接完成:
private TaskCompletionSource<bool> _connectionReadyTcs;

// 初始化连接的地方
_connectionReadyTcs = new TaskCompletionSource<bool>();
connection.StatusChanged += (sender, args) =>
{
    if (args.Status == AppServiceConnectionStatus.Connected)
    {
        _connectionReadyTcs.TrySetResult(true);
    }
    else
    {
        _connectionReadyTcs.TrySetException(new InvalidOperationException("连接未建立"));
    }
};

// 启动WinForms后要发消息时
await _connectionReadyTcs.Task;
await SendToUWPAsync(content);

3. 确保在正确的线程上调用SendMessageAsync

UWP的AppServiceConnection操作需要在UI线程(或拥有CoreDispatcher的线程)上执行,要是WinForms组件在非UI线程初始化,就容易触发这个异常。可以用UWP的CoreDispatcher调度:

private async Task SendToUWPAsync(object content)
{
    // 获取UWP主UI线程的Dispatcher
    var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        ValueSet message = new ValueSet();
        // 填充message...

        if (connection?.Status == AppServiceConnectionStatus.Connected)
        {
            var response = await connection.SendMessageAsync(message);
            // 处理响应
        }
    });
}

4. 加个重试机制兜底

即使做了前面的检查,偶尔还是可能因为连接波动触发异常,加个简单的重试逻辑能提高稳定性:

private async Task<bool> SendToUWPWithRetryAsync(object content, int retryCount = 2)
{
    for (int i = 0; i <= retryCount; i++)
    {
        try
        {
            await SendToUWPAsync(content);
            return true;
        }
        catch (InvalidOperationException)
        {
            if (i == retryCount) throw; // 最后一次重试失败再抛出
            await Task.Delay(100); // 等待100ms后重试
        }
    }
    return false;
}

核心就是这几个点:确保连接就绪、避免async void、在正确线程调用、加上异常处理和重试。调整后应该就能解决这个时好时坏的异常了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:19:10