我们在写WinForm程序的时候会发现,你在非UI线程里的的更改UI里的对象时会抛出异常。
这个时候就会要求使用控件的跨线程判断与操作,一个一个的元素的去写太麻烦了。我写了个简单的扩展。
然后,就像只有一个线程一样的去操作吧。
using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace System.Windows.Forms { public static class FormExtensions { public static void Push(this TextBox box, string message, TraceLevel level = TraceLevel.Info) { box.SafeChange(() => { if (box.Lines.Length > 5000) { box.Clear(); } box.AppendText($"[{DateTime.Now:HH:mm:ss fff}] [{level}] {message} {Environment.NewLine}"); }); } public static void Begin(this Button button) { button.SafeChange(() => { button.Tag = button.Text; button.Text = $"{button.Text} ..."; button.Enabled = false; }); } public static void End(this Button button) { button.SafeChange(() => { button.Text = (string)button.Tag; button.Enabled = true; }); } #region Contrl Thread Safe operation. public static void SafeChange(this Control control, Action action) { if (control.InvokeRequired) { control.Invoke(_safeChangeAction, control, action); } else { _safeChangeAction(control, action); } } private static Action<Control, Action> _safeChangeAction = SafeChangeForAction; private static void SafeChangeForAction(Control button, Action action) { action?.Invoke(); } #endregion } }
在主线程里操作时直接调用即可。
txtMessage.Push(msg);
或者你再包装成一个方法。