返回提交历史

XFEstudio/MyFirstRespo

修复未处理异常问题

08fe41d
X
XFEstudio <mail@xfegzs.com>
提交于

代码差异

5 个文件 +242 -19
Modified XFEToolBox/App.xaml.cs +34 -0
@@ -11,4 +11,38 @@ public partial class App : Application
11 11 {
12 12 this.InitializeComponent();
13 13 }
14 protected override void OnStartup(StartupEventArgs e)
15 {
16 base.OnStartup(e);
17
18 // 注册 UI 线程未处理异常事件
19 this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
20
21 // 注册非 UI 线程未处理异常事件
22 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
23
24 // 注册任务调度程序未观察到的任务异常事件
25 TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
26 }
27
28 void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
29 {
30 // 处理 UI 线程未处理的异常
31 MessageBox.Show("UI线程未处理异常:" + e.Exception.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
32 e.Handled = true; // 设置为 true 表示异常已处理,防止应用程序退出
33 }
34
35 void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
36 {
37 // 处理非 UI 线程未处理的异常
38 Exception ex = e.ExceptionObject as Exception;
39 MessageBox.Show("非UI线程未处理异常:" + ex?.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
40 }
41
42 void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
43 {
44 // 处理任务调度程序未观察到的任务异常
45 MessageBox.Show("非主线程未处理异常:" + e.Exception.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
46 e.SetObserved(); // 防止程序崩溃
47 }
14 48 }
Added XFEToolBox/Utilities/XFEConsoleClientInfo.cs +30 -0
@@ -0,0 +1,30 @@
1 using XFEExtension.NetCore.CyberComm;
2
3 namespace XFEExtension.NetCore.XFEConsole;
4
5 /// <summary>
6 /// XFE控制台客户端信息
7 /// </summary>
8 /// <param name="clientName">客户端名称</param>
9 /// <param name="clientUUID">客户端唯一标识符</param>
10 /// <param name="password">客户端连接时密码</param>
11 /// <param name="eventArgs">事件参数</param>
12 public class XFEConsoleClientInfo(string clientName, string clientUUID, string password, CyberCommServerEventArgs eventArgs)
13 {
14 /// <summary>
15 /// 客户端名称
16 /// </summary>
17 public string ClientName { get; set; } = clientName;
18 /// <summary>
19 /// 客户端唯一标识符
20 /// </summary>
21 public string ClientUUID { get; set; } = clientUUID;
22 /// <summary>
23 /// 客户端密码
24 /// </summary>
25 public string Password { get; set; } = password;
26 /// <summary>
27 /// 事件参数
28 /// </summary>
29 public CyberCommServerEventArgs EventArgs { get; set; } = eventArgs;
30 }
Added XFEToolBox/Utilities/XFEConsoleTerminalServer.cs +149 -0
@@ -0,0 +1,149 @@
1 using System.Net.WebSockets;
2 using XFEExtension.NetCore.CyberComm;
3 using XFEExtension.NetCore.DelegateExtension;
4
5 namespace XFEExtension.NetCore.XFEConsole;
6
7 /// <summary>
8 /// XFE控制台终端服务器
9 /// </summary>
10 public class XFEConsoleTerminalServer
11 {
12 /// <summary>
13 /// 服务器
14 /// </summary>
15 public CyberCommServer Server { get; set; }
16 /// <summary>
17 /// 密码
18 /// </summary>
19 public string Password { get; set; }
20 /// <summary>
21 /// Socket客户端-客户端信息字典
22 /// </summary>
23 public Dictionary<WebSocket, XFEConsoleClientInfo> ClientInfoDictionary { get; set; } = [];
24 /// <summary>
25 /// 客户端连接事件
26 /// </summary>
27 public event XFEEventHandler<XFEConsoleTerminalServer, XFEConsoleClientInfo>? Connected;
28 /// <summary>
29 /// 客户端断开连接事件
30 /// </summary>
31 public event XFEEventHandler<XFEConsoleTerminalServer, XFEConsoleClientInfo>? Disconnected;
32 /// <summary>
33 /// 接收到客户端消息触发
34 /// </summary>
35 public event XFEEventHandler<XFEConsoleClientInfo, string>? MessageReceived;
36 /// <summary>
37 /// 发生错误
38 /// </summary>
39 public event XFEEventHandler<XFEConsoleClientInfo, Exception>? ErrorOccurred;
40 /// <summary>
41 /// 服务器启动事件
42 /// </summary>
43 public event XFEEventHandler<XFEConsoleTerminalServer>? ServerStarted;
44 /// <summary>
45 /// XFE控制台终端服务器
46 /// </summary>
47 /// <param name="port">端口号</param>
48 /// <param name="localOnly">是否只在本地开启</param>
49 /// <param name="password">密码(默认为空)</param>
50 public XFEConsoleTerminalServer(int port, bool localOnly = true, string password = "")
51 {
52 Password = password;
53 if (localOnly)
54 Server = new CyberCommServer($"http://localhost:{port}/");
55 else
56 Server = new CyberCommServer(port);
57 Server.ServerStarted += Server_ServerStarted;
58 Server.ClientConnected += Server_ClientConnected;
59 Server.ConnectionClosed += Server_ConnectionClosed;
60 Server.MessageReceived += Server_MessageReceived;
61 }
62 /// <summary>
63 /// XFE控制台终端服务器
64 /// </summary>
65 /// <param name="ipAddress">IP地址</param>
66 /// <param name="password">密码(默认为空)</param>
67 public XFEConsoleTerminalServer(string[] ipAddress, string password = "")
68 {
69 Password = password;
70 Server = new CyberCommServer(ipAddress);
71 Server.ServerStarted += Server_ServerStarted;
72 Server.ClientConnected += Server_ClientConnected;
73 Server.ConnectionClosed += Server_ConnectionClosed;
74 Server.MessageReceived += Server_MessageReceived;
75 }
76
77 private void Server_MessageReceived(object? sender, CyberCommServerEventArgs e)
78 {
79 switch (e.MessageType)
80 {
81 case BackMessageType.Text:
82 MessageReceived?.Invoke(ClientInfoDictionary[e.CurrentWebSocket], e.TextMessage!);
83 break;
84 case BackMessageType.Binary:
85 break;
86 case BackMessageType.Error:
87 ErrorOccurred?.Invoke(ClientInfoDictionary[e.CurrentWebSocket], e.Exception!);
88 break;
89 default:
90 break;
91 }
92 }
93
94 private void Server_ConnectionClosed(object? sender, CyberCommServerEventArgs e)
95 {
96 if (ClientInfoDictionary.TryGetValue(e.CurrentWebSocket, out XFEConsoleClientInfo? clientInfo))
97 {
98 ClientInfoDictionary.Remove(e.CurrentWebSocket);
99 Disconnected?.Invoke(this, clientInfo);
100 }
101 }
102
103 private async void Server_ClientConnected(object? sender, CyberCommServerEventArgs e)
104 {
105 try
106 {
107 if (e.WSHeader["ClientName"] is not null && e.WSHeader["ClientID"] is not null && e.WSHeader["Password"] is not null)
108 {
109 var password = e.WSHeader["Password"]!;
110 var clientName = e.WSHeader["ClientName"]!;
111 var clientUUID = e.WSHeader["ClientID"]!;
112 if (password == Password)
113 {
114 var clientInfo = new XFEConsoleClientInfo(clientName, clientUUID, password, e);
115 ClientInfoDictionary.Add(e.CurrentWebSocket, clientInfo);
116 Connected?.Invoke(this, clientInfo);
117 }
118 return;
119 }
120 }
121 catch { }
122 try
123 {
124 await e.Close();
125 }
126 catch
127 {
128 try
129 {
130 e.ForceClose();
131 }
132 catch { }
133 }
134 }
135
136 private void Server_ServerStarted(object? sender, EventArgs e)
137 {
138 ClientInfoDictionary = [];
139 ServerStarted?.Invoke(this);
140 }
141 /// <summary>
142 /// 启动服务器
143 /// </summary>
144 /// <returns></returns>
145 public async Task StartServer()
146 {
147 await Server.StartCyberCommServer();
148 }
149 }
Modified XFEToolBox/ViewModel/ConsolePageViewModel.cs +29 -18
@@ -11,7 +11,7 @@ using XFEToolBox.Views.Pages;
11 11
12 12 namespace XFEToolBox.ViewModel;
13 13
14 public partial class ConsolePageViewModel : ObservableObject
14 public partial class ConsolePageViewModel(ConsolePage viewPage) : ObservableObject
15 15 {
16 16 [ObservableProperty]
17 17 private bool canStartServer = true;
@@ -23,14 +23,9 @@ public partial class ConsolePageViewModel : ObservableObject
23 23 private bool canCleanUp = false;
24 24
25 25 private bool lastLineIsEnd = true;
26 public ConsolePage ViewPage { get; set; }
26 public ConsolePage ViewPage { get; set; } = viewPage;
27 27 public XFEConsoleTerminalServer? TerminalServer { get; set; }
28 28
29 public ConsolePageViewModel(ConsolePage viewPage)
30 {
31 ViewPage = viewPage;
32 }
33
34 29 public async Task StartConsoleServer()
35 30 {
36 31 TerminalServer = new XFEConsoleTerminalServer(ConsoleProfile.ConsolePort, ConsoleProfile.LocalOnly, ConsoleProfile.ConsolePassword);
@@ -39,14 +34,24 @@ public partial class ConsolePageViewModel : ObservableObject
39 34 TerminalServer.Disconnected += TerminalServer_Disconnected;
40 35 TerminalServer.MessageReceived += TerminalServer_MessageReceived;
41 36 TerminalServer.ErrorOccurred += TerminalServer_ErrorOccurred;
42 await TerminalServer.StartServer();
37 await Task.Run(async () =>
38 {
39 try
40 {
41 await TerminalServer.StartServer();
42 }
43 catch (Exception ex)
44 {
45 TerminalServer_ErrorOccurred(null!, ex);
46 }
47 });
43 48 }
44 49
45 50 public void ShutDownServer()
46 51 {
47 52 try
48 53 {
49 TerminalServer?.Server.Server.Close();
54 TerminalServer?.Server.Server.Abort();
50 55 }
51 56 catch { }
52 57 TerminalServer = null;
@@ -98,17 +103,23 @@ public partial class ConsolePageViewModel : ObservableObject
98 103 var lastControl = ViewPage.consoleStackPanel.Children.Count > 0 ? ViewPage.consoleStackPanel.Children[^1] : null;
99 104 if (lastControl is TextBlock lastTextBlock)
100 105 {
101 var inLineList = DecoratedTextConverter.ConvertToInlineList(message, defaultColor);
102 lastTextBlock.Inlines.AddRange(inLineList);
103 lastLineIsEnd = isLineEnd;
104 return;
106 ViewPage.Dispatcher.Invoke(() =>
107 {
108 var inLineList = DecoratedTextConverter.ConvertToInlineList(message, defaultColor);
109 lastTextBlock.Inlines.AddRange(inLineList);
110 lastLineIsEnd = isLineEnd;
111 });
105 112 }
113 return;
106 114 }
107 var textBlock = DecoratedTextConverter.ConvertToTextBlock(message, defaultColor);
108 textBlock.TextWrapping = System.Windows.TextWrapping.Wrap;
109 textBlock.FontSize = 13;
110 textBlock.FontFamily = new FontFamily("Consolas");
111 ViewPage.consoleStackPanel.Children.Add(textBlock);
115 ViewPage.Dispatcher.Invoke(() =>
116 {
117 var textBlock = DecoratedTextConverter.ConvertToTextBlock(message, defaultColor);
118 textBlock.TextWrapping = System.Windows.TextWrapping.Wrap;
119 textBlock.FontSize = 13;
120 textBlock.FontFamily = new FontFamily("Consolas");
121 ViewPage.consoleStackPanel.Children.Add(textBlock);
122 });
112 123 lastLineIsEnd = isLineEnd;
113 124 }
114 125 /// <summary>
Modified XFEToolBox/XFEToolBox.csproj +0 -1
@@ -37,7 +37,6 @@
37 37 <PackageReference Include="XFEExtension.NetCore.AutoPath" Version="1.0.1" />
38 38 <PackageReference Include="XFEExtension.NetCore.InputSimulator" Version="2.2.0" />
39 39 <PackageReference Include="XFEExtension.NetCore.TodoHighLight" Version="1.0.0" />
40 <PackageReference Include="XFEExtension.NetCore.XFEConsole" Version="1.0.0" />
41 40 </ItemGroup>
42 41
43 42 <ItemGroup>