程式碼中 SetText 方法內呼叫 this.Invoke(d, ...),委派 d 指向 SetText 自身,形成遞迴。若 InvokeRequired 永真,將陷入無限遞迴(堆疊溢位)。
this 指向目前物件實例,SetText 是實例方法,自然可在內部呼叫 this.SetText(...) 或透過委派 new SetTextCallback(SetText)。private void SetText(string text) {
if (this.textBox1.InvokeRequired) {
SetTextCallback d = new SetTextCallback(SetText); // 指向自己
this.Invoke(d, new object[] { text }); // 在 UI 執行緒再次呼叫 SetText
} else {
this.textBox1.Text = text;
}
}
若 InvokeRequired 判斷邏輯有誤(如永遠回傳 true),將無限遞迴。正確模式應分離 UI 更新邏輯:
// 公開方法:供背景執行緒呼叫
public void SetText(string text) {
if (textBox1.InvokeRequired) {
// 使用 lambda 或獨立方法,避免直接遞迴自身
textBox1.Invoke(new Action<string>(SetTextSafe), text);
} else {
SetTextSafe(text);
}
}
// 純 UI 更新邏輯:不含 Invoke 判斷
private void SetTextSafe(string text) {
textBox1.Text = text;
}
// .NET 4.5+ / C# 5+
public async Task SetTextAsync(string text) {
if (textBox1.InvokeRequired) {
await Task.Run(() => textBox1.Invoke(new Action(() => textBox1.Text = text)));
} else {
textBox1.Text = text;
}
}
// 或使用 SynchronizationContext (WinForms/WPF 通用)
private readonly SynchronizationContext _uiContext = SynchronizationContext.Current;
public void SetText(string text) {
_uiContext.Post(_ => textBox1.Text = text, null);
}
SetText 透過委派遞迴自身,缺乏終止條件 → 死迴圈風險。async/await + SynchronizationContext 或 Control.Invoke,更清晰安全。