2012-08-17 65 views
0

我创建了一个winforms多线程应用程序。只要主线程启动,就会在另一个新产生的后台线程上创建启动画面的窗体。UI有时会挂起(Windows窗体C#)

Code: 
static SplashForm sf = new SplashForm(); 
main() 
{ 
... 
    Thread t = new Thread(new ThreadStart(runSplash)); 
    t.IsBackground = true; 
    t.start(); 
Application.Run(new MainForm()); 
... 
} 

void runSplash() 
{ 
Application.Run(sf); 
} 

后来在主线程上创建了一个MainForm,在mainform的加载事件处理程序中正在关闭splash窗体。

有时UI挂起。

即它不响应键盘或鼠标操作。但是主线程和其他线程正在优雅地运行。

得到使用间谍++

<00001> 000103A6 S WM_WINDOWPOSCHANGING lpwp:003DF0DC 
<00002> 000103A6 R WM_WINDOWPOSCHANGING 
<00003> 000103A6 S WM_NCPAINT hrgn:00000001 
<00004> 000103A6 S WM_GETTEXT cchTextMax:510 lpszText:003DDBAC 
<00005> 000103A6 R WM_GETTEXT cchCopied:37 lpszText:003DDBAC ("I") 
<00006> 000103A6 R WM_NCPAINT 
<00007> 000103A6 S WM_ERASEBKGND hdc:D5010AC2 
<00008> 000103A6 R WM_ERASEBKGND fErased:True 
<00009> 000103A6 S WM_WINDOWPOSCHANGED lpwp:003DF0DC 
<00010> 000103A6 R WM_WINDOWPOSCHANGED 
<00011> 000103A6 S WM_ACTIVATEAPP fActive:True dwThreadID:000008A8 
<00012> 000103A6 R WM_ACTIVATEAPP 
<00013> 000103A6 S WM_NCACTIVATE fActive:True 
<00014> 000103A6 R WM_NCACTIVATE 
<00015> 000103A6 S WM_ACTIVATE fActive:WA_ACTIVE fMinimized:False hwndPrevious:(null) 
<00016> 000103A6 R WM_ACTIVATE 
<00017> 000103A6 S WM_IME_SETCONTEXT fSet:1 (LONG)iShow:C000000F 
<00018> 000103A6 S WM_IME_NOTIFY dwCommand:00000002 dwData:00000000 
<00019> 000103A6 R WM_IME_NOTIFY 
<00020> 000103A6 R WM_IME_SETCONTEXT 
<00021> 000103A6 S WM_SETFOCUS hwndLoseFocus:(null) 
<00022> 000103A6 R WM_SETFOCUS 
<00023> 000103A6 P WM_PAINT hdc:00000000 
<00024> 000103A6 S WM_SETCURSOR hwnd:000103A6 nHittest:FFFE wMouseMsg:WM_MOUSEMOVE 
<00025> 000103A6 R WM_SETCURSOR fHaltProcessing:False 
<00026> 000103A6 S WM_SETCURSOR hwnd:000103A6 nHittest:FFFE wMouseMsg:WM_MOUSEMOVE 
<00027> 000103A6 R WM_SETCURSOR fHaltProcessing:False 
<00028> 000103A6 S WM_NCACTIVATE fActive:False 
<00029> 000103A6 S WM_GETTEXT cchTextMax:510 lpszText:003DDBAC 
<00030> 000103A6 R WM_GETTEXT cchCopied:37 lpszText:003DDBAC ("I") 
<00031> 000103A6 R WM_NCACTIVATE fDeactivateOK:True 
<00032> 000103A6 S WM_ACTIVATE fActive:WA_INACTIVE fMinimized:False hwndPrevious:(null) 
<00033> 000103A6 R WM_ACTIVATE 
<00034> 000103A6 S WM_ACTIVATEAPP fActive:False dwThreadID:00000BB0 
<00035> 000103A6 R WM_ACTIVATEAPP 
<00036> 000103A6 S WM_KILLFOCUS hwndGetFocus:(null) 
<00037> 000103A6 R WM_KILLFOCUS 
<00038> 000103A6 S WM_IME_SETCONTEXT fSet:0 (LONG)iShow:C000000F 
<00039> 000103A6 S WM_IME_NOTIFY dwCommand:00000001 dwData:00000000 
<00040> 000103A6 R WM_IME_NOTIFY 
<00041> 000103A6 R WM_IME_SETCONTEXT 
<00042> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 
<00043> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 
<00044> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 
<00045> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 
<00046> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 
<00047> 000103A6 P message:0xC185 [Registered:"WindowsForms12_ThreadCallbackMessage"] wParam:00000000 lParam:00000000 

是什么原因造成这个问题,如何摆脱这种以下日志消息?

+1

如果没有进一步的信息,就不可能说出这个问题。例如它究竟是什么时候挂?那时执行什么代码? – 2012-08-17 05:49:28

+0

当它处于挂起状态时,您可以附加到应用程序并检查Visual Studio中的“线程”窗口中的线程。这将指出你在哪个线程等待哪个对象/线程的正确方向。 – 2012-08-17 05:52:22

回答

3

为什么选择spy ++?你需要创建一个内存转储(使用winDBG等)并分析它。

有时UI挂起,即它不响应键盘或鼠标操作。但是主线程和其他线程正在优雅地运行。

GUI需要在主线程上。此代码显示在另一个线程的启动画面:

Thread t = new Thread(new ThreadStart(runSplash)); 
t.IsBackground = true; 
t.start(); 

Windows窗体控件没有本质上就是线程安全的,你可以随处读了这一点,如:
In WinForms, why can't you update UI controls from other threads?

把你所有的UI东西回到主线程中,让我们知道问题是否仍然存在。

+0

为什么我们不应该在一个线程上创建第一个表单而在另一个线程上创建第二个表单? – user186246 2012-08-17 07:18:57

+0

初始窗体在主线程上创建,但它正在主线程以外的新线程上运行。 – user186246 2012-08-17 07:40:02