0
這是我的代碼被執行:多線程 - 窗口先關閉,然後創建,即使在代碼創建的方法被稱爲第一
OpenMyWindowInNewThread(1280, 1024, 5);
//do some stuff
CloseMyWindow();
這裏是方法:
public void OpenMyWindowInNewThread(int width, int height, int top)
{
thread = new Thread(x => OpenMyWindow(width, height, top));
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public void CloseMyWindow()
{
if (myWindow != null)
{
myWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
myWindow.Close();
myWindow = null;
}));
}
}
private void OpenMyWindow(int width, int height, int top)
{
myWindow = new MyView();
myWindow.Closed += new EventHandler(MyWindow_Closed);
myWindow.Width = width;
myWindow.Height = height;
myWindow.Top = top;
myWindow.Left = 0;
myWindow.ShowDialog();
}
當我第一次調用第一個代碼時,屏幕顯示並關閉,因爲它應該。但是,當我第二次執行代碼時,會發生以下情況:首先調用OpenMyWindowInNewThread(),然後調用OpenMyWindow(),然後調用CloseMyWindow()方法中的if條件,之後調用MyView() OpenMyWindow()方法中的構造函數。所以,窗口永遠不會關閉,因爲它首先關閉,而不是創建。
這是怎麼發生的?有人可以解釋嗎?
您正在使用單獨的線程來創建新窗口。該線程被設置爲後臺優先級。無法保證在關閉通話前它會執行。這是一個典型的競賽條件。在關閉窗口中使用manualresetevent和block,直到觸發爲止 – thorkia 2014-11-14 16:26:35
不要創建多個UI線程。不要。爲整個應用程序使用單個UI線程。你只是將自己置身於一個試圖處理多個消息循環的傷害世界。 – Servy 2014-11-14 16:27:23
你的描述實際上沒有意義。在構造函數返回之前,不能將myWindow設置爲新的表單引用。所以'CloseMyWindow()'在構造函數之前不能看到它非空。也就是說,正如其他人已經注意到的那樣,你確實在這裏有一場比賽,是的你應該在一個線程上完成所有的UI。如果您希望在進行其他一些處理時顯示對話框,請在UI線程中顯示對話框,然後使用「BackgroundWorker」或其他輔助線程執行其他處理(這可能不應在主UI上完成線程無論如何!) – 2014-11-14 21:53:12