C# Result类实时日志更新重复显示问题求助
问题原因分析
- 日志推送逻辑错误:
Result类的UpdateLog方法每次发送的是日志的完整内容(Message.ToString()),而非仅新增的单条日志。 - UI更新逻辑错误:
UpdateTextBoxLog方法用+=将收到的内容追加到文本框,等于每次把全量日志重复叠加,最终导致日志重复显示。
举个例子:
- 第一次调用
UpdateLog("CP"),发送完整日志"CP\n",文本框内容为"CP\n"; - 第二次调用
UpdateLog("Test"),发送完整日志"CP\nTest\n",文本框通过+=追加后变成"CP\n" + "CP\nTest\n",也就是"CP\nCP\nTest\n",以此类推就出现了重复日志。
解决方案
方案1:推送单条新增日志(推荐)
修改Result类,让LogUpdated事件仅传递新增的单条日志,同时保留Message存储完整日志:
public class Result { public bool Success { get; set; } public StringBuilder Message { get; set; } public bool IsSuccess => Success; public event Action<string> LogUpdated; public Result() { Success = false; Message = new StringBuilder(); } public void UpdateLog(string message) { var logLine = $"{message}\n"; Message.Append(logLine); OnLogUpdated(logLine); // 仅传递新增的单条日志 } protected virtual void OnLogUpdated(string updatedLog) { LogUpdated?.Invoke(updatedLog); } }
UI更新方法保持追加逻辑(此时收到的是单条日志),同时补充跨线程安全处理(如果业务方法在非UI线程执行):
private void UpdateTextBoxLog(string updatedLog) { if (tb_log.InvokeRequired) { tb_log.Invoke(new Action<string>(UpdateTextBoxLog), updatedLog); return; } tb_log.Text += updatedLog; }
方案2:推送全量日志,UI直接替换
如果需要保持推送全量日志的逻辑,将UI更新改为直接替换文本框内容,而非追加:
private void UpdateTextBoxLog(string updatedLog) { if (tb_log.InvokeRequired) { tb_log.Invoke(new Action<string>(UpdateTextBoxLog), updatedLog); return; } tb_log.Text = updatedLog; // 用=替换而非+=追加 }
额外注意事项
- 事件重复订阅:检查是否存在多次执行
result.LogUpdated += UpdateTextBoxLog的情况,这会导致同一条日志被多次处理。可在订阅前先取消订阅:result.LogUpdated -= UpdateTextBoxLog; result.LogUpdated += UpdateTextBoxLog; - 跨线程安全:若业务方法在非UI线程执行,必须通过
Invoke/BeginInvoke切换到UI线程更新控件,否则会触发跨线程操作异常。
内容的提问来源于stack exchange,提问作者jeheel
相关产品推荐
相关产品推荐

