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

UWP语音转文字应用:关闭时执行WebSocket断开操作遇Closing事件相关错误的技术求助

解决UWP应用关闭时才断开WebSocket连接的问题

首先得明确你遇到错误的核心原因:Closing是Window类的事件,不是Page类的。你在Page的XAML里直接绑定Closing属性,编译器自然找不到这个成员,所以才会抛出XDG0012、XLS0413这些错误。另外你自己定义的Closing委托也是多余的,System.ComponentModel.CancelEventHandler已经是现成的委托类型,不需要重复定义。

下面是具体的修正方案,帮你实现"仅当用户关闭窗口时断开WebSocket"的需求:


步骤1:修正XAML代码

移除Page标签里的Closing="OnClosing"属性,因为Page根本没有这个事件:

<Page x:Class="SpeechToTextApp.MainPage" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="using:SpeechToTextApp" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      mc:Ignorable="d" 
      Height="168" Width="410">
    <Page.Resources>
        <SolidColorBrush x:Key="TranslucentBlackBrush" Color="Black" Opacity="1"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Button Content="Start Recording" Click="btnRec_Click" Visibility="Visible" Background="Green" x:Name="btnRec" Height="47" Width="155" Margin="31,106,0,0" VerticalAlignment="Top"/>
        <Button Content="Stop Recording" Click="btnStop_Click" Visibility="Visible" Background="Red" x:Name="btnStop" Margin="245,106,0,0" VerticalAlignment="Top" Height="47" Width="139"/>
    </Grid>
</Page>

步骤2:修正C#代码

在MainPage的构造函数中,获取当前应用的主窗口,订阅它的Closing事件;同时优化异步操作的处理,避免阻塞UI线程:

using System;
using System.Threading.Tasks;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using Windows.Storage;
using Windows.System.Display;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.IO;
using Windows.Storage.Streams;
using System.ComponentModel; // 确保引入这个命名空间

namespace SpeechToTextApp
{
    public sealed partial class MainPage : Page
    {
        private static Client.Client client;
        
        public MainPage()
        {
            this.InitializeComponent();
            client = new Client.Client();
            _ = client.ConnectToServer(); // 用弃元运算符避免未使用任务的警告

            // 获取当前窗口并订阅Closing事件
            var currentWindow = Window.Current;
            currentWindow.Closing += OnClosing;
        }

        // 改为async方法,正确处理异步断开逻辑
        private async void OnClosing(object sender, CancelEventArgs e)
        {
            // 先阻止窗口立即关闭,等待断开连接完成
            e.Cancel = true;
            
            try
            {
                await client.DisconnectFromServer();
                // 断开成功后,手动关闭窗口
                (sender as Window).Close();
            }
            catch (Exception ex)
            {
                // 记录断开时的异常(可选)
                System.Diagnostics.Debug.WriteLine($"断开WebSocket出错: {ex.Message}");
                // 即使出错,也关闭窗口
                (sender as Window).Close();
            }
        }

        void btnRec_Click(object sender, RoutedEventArgs e)
        {
            // 你的录制逻辑
        }

        async void btnStop_Click(object sender, RoutedEventArgs e)
        {
            // 你的停止录制逻辑
        }
    }
}

关键说明

  1. 事件订阅的正确姿势:UWP中只有Window才有Closing事件,所以必须通过Window.Current获取当前窗口再订阅事件,不能直接在Page的XAML里绑定。
  2. 异步操作优化:不要用task.Wait()阻塞UI线程,这可能导致死锁。改用await等待断开操作完成,同时先设置e.Cancel = true阻止窗口立即关闭,等断开完成后再手动关闭窗口。
  3. 额外场景补充:如果你的应用可能被系统强制终止(比如后台资源回收),可以额外订阅Application.Current.Terminated事件,确保在极端场景下也能执行断开逻辑。不过根据你的需求,Window.Closing已经能覆盖用户点击窗口关闭按钮的核心场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:07:50