[英]Ensure new form is created on the UI thread
我有多個寫入日志表單的線程。 無論哪個線程收到第一條消息,都將即時創建表單。 我為每個表單更新使用MyForm.InvokeRequired
/ .Invoke(…)
,但是代碼有時會在主線程處於狀態.WaitForWaitHandle的情況下死鎖 。
據我了解-盡管可能完全不合時宜,但問題是有時WorkerThread創建了表單。 從此以后,即使隨后從UI線程更新了表單, .InvokeRequired
也將始終為true。 在后一種情況下,UI線程可能正在等待自身嗎?
我希望可以通過在UI線程本身上創建表單來解決此問題,但是我不知道MyForm == null時從哪個控件開始。
注意 :后台有一個多線程API,其中的線程用於接收/發送/處理我需要跟蹤的消息。
簡化示例:
public static LogForm MyForm;
public static void AddLogLine(string inText) // is called from multiple threads
{
if (MyForm == null) MyForm = new LogForm();
if (MyForm.InvokeRequired)
MyForm.Invoke(new Action<LogForm, string>(_appendText), MyForm ,inText); // deadlock, UI thread state: .WaitForWaitHandle
else
_appendText(MyForm ,inText);
}
我建議您閱讀有關Synchornization上下文的文章: https ://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I
每個表單/對話框/用戶控件都應在UI線程上初始化,實現這一目標的一種可行方法是為您的主表單創建一個公共靜態引用:
public static Form1 StaticReference;
在構造函數上設置它:
public Form1()
{
StaticReference = this;
}
然后在其他地方的代碼上:
public static LogForm MyForm;
public static void AddLogLine(string inText) // is called from multiple threads
{
<namespace>.StaticReference.BeginInvoke((MethodInvoker)delegate
{
if (MyForm == null)
MyForm = new LogForm();
Do whatever you want with MyForm within this block.
});
}
您發現的任何解決方案仍將需要通過UI線程將調用編組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.