在非表單類別 (如網路監聽、背景執行緒) 中需要更新 UI 控制項 (ListView、TextBox 等),但無法直接存取表單實例的控制項 (非 public) 或方法。
public partial class MainForm : Form
{
public event Action<string> OnMessageReceived;
public MainForm() { InitializeComponent(); }
private void AppendLog(string msg)
{
if (listView1.InvokeRequired)
listView1.Invoke(new Action<string>(AppendLog), msg);
else
listView1.Items.Add(msg);
}
// 供外部呼叫的 public 方法
public void ReceiveMessage(string msg) => AppendLog(msg);
}
public class NetworkListener
{
private MainForm _form;
public NetworkListener(MainForm form) { _form = form; }
public void OnDataReceived(string data)
{
// 方式 A: 直接呼叫 public 方法 (需確保執行緒安全)
_form.ReceiveMessage(data);
// 方式 B: 觸發事件 (表單自行處理 Invoke)
_form.OnMessageReceived?.Invoke(data);
}
}
public interface ILogView
{
void AppendLog(string message);
}
public partial class MainForm : Form, ILogView
{
public void AppendLog(string message) { /* Invoke 實作 */ }
}
public class NetworkListener
{
private ILogView _view;
public NetworkListener(ILogView view) { _view = view; }
public void OnDataReceived(string data) => _view.AppendLog(data);
}
public partial class MainForm : Form
{
public static MainForm Instance { get; private set; }
public MainForm() { InitializeComponent(); Instance = this; }
}
// 任意處呼叫
MainForm.Instance?.ReceiveMessage("msg");
缺點:強耦合、難測試、多實例場景失效、記憶體洩漏風險。
所有跨執行緒 UI 操作必須透過 Control.Invoke 或 BeginInvoke 執行於 UI 執行緒:
if (control.InvokeRequired)
control.Invoke((MethodInvoker)delegate { /* UI 操作 */ });
else
/* UI 操作 */;
Invoke 邏輯,對外暴露執行緒安全的 public 方法。BackgroundWorker、Task.Run + Progress<T>、SynchronizationContext。