WPF .NET 3.5开发聊天类程序使用Dispatcher仍出现窗口锁死问题咨询
WPF .NET 3.5 聊天机器人UI阻塞问题解答
问题判定
你的Dispatcher使用方式不正确,这是窗口锁死的直接原因。
错误原因
WPF的Dispatcher是UI线程的专属调度器,Dispatcher.BeginInvoke只是将ResponsServer委托按指定优先级加入UI线程的执行队列,整个方法的逻辑仍然运行在UI线程上。你代码中Thread.Sleep(3000)模拟的服务端延迟、get(txt_input.Text)的网络请求都是阻塞型逻辑,直接在UI线程运行就会导致窗口无响应。
适配.NET 3.5的修复方案
.NET 3.5不支持Task异步API,你可以通过子线程处理耗时逻辑,仅在操作UI时通过Dispatcher调度回UI线程执行即可,参考代码如下:
private void send_Click(object sender, RoutedEventArgs e) { // UI操作直接在当前线程执行 stack.Children.Add(new UserControl_Send() { DataSend = txt_input.Text, DateTimeBot = DateTime.Now.ToString("HH:mm") }); // 提前缓存输入内容,避免子线程直接访问UI控件报错 string inputContent = txt_input.Text; // 开启后台子线程处理耗时请求 Thread serverRequestThread = new Thread(() => ProcessServerRequest(inputContent)); serverRequestThread.IsBackground = true; serverRequestThread.Start(); } private void ProcessServerRequest(string input) { // 耗时逻辑全部在子线程运行,不会阻塞UI Thread.Sleep(3000); string response = get(input); // 仅操作UI时调度回UI线程 Dispatcher.Invoke(new Action(() => { stack.Children.Add(new UserControl_Receive() { DataRecive = response, DateTimeBot = DateTime.Now.ToString("HH:mm"), }); })); }
注意事项
- 子线程禁止直接读写UI控件的属性,所有UI相关操作必须放到Dispatcher的委托中执行,否则会抛出跨线程访问异常
- 子线程设置
IsBackground = true可以避免窗口关闭后线程仍在后台运行的问题
内容的提问来源于stack exchange,提问作者vahid
相关产品推荐
相关产品推荐

