2009-09-28 69 views
3

我試圖從不同的線程訪問的形式來其上的形式被創造了,終於結束了一個錯誤:獲取跨線程操作SetWindowPos()無效

Cross thread operation not valid

代碼:

public static void MakeTopMost(Form form) 
{ 
    SetWindowPos(form.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); 
} 

我傳遞一個窗體,正在另一個線程中運行。我試過測試InvokeRequired,但它總是假的。

我是線程新手。

+0

[Cross-thread operation not valid]的可能重複(http://stackoverflow.com/questions/5037470/cross-thread-operation-not-valid) – abatishchev 2012-12-09 21:01:06

回答

13

確保您正在測試正確的對象爲InvokeRequired

public static void MakeTopMost(Form form) 
{ 
    if (form.InvokeRequired) 
    { 
     form.Invoke((Action)delegate { MakeTopMost(form); }); 
     return; 
    } 

    SetWindowPos(form.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); 
} 

我喜歡的擴展方法是這樣來包裝這一切了:

public static class SynchronizeInvokeUtil 
{ 
    public static void SafeInvoke(this ISynchroniseInvoke sync, Action action) 
    { 
     if (sync.InvokeRequired) 
      sync.Invoke(action); 
     else 
      action(); 
    } 

    public static void SafeBeginInvoke(this ISynchroniseInvoke sync, 
             Action action) 
    { 
     if (sync.InvokeRequired) 
      sync.BeginInvoke(action); 
     else 
      action(); 
    } 
} 

然後,您可以只要致電:

form.SafeInvoke(() => SetWindowPos(form.Handle, HWND_TOPMOST, 
            0, 0, 0, 0, TOPMOST_FLAGS)); 

這可能是最可讀的。

請注意,如果您在表單類本身內使用此類,則必須使用this.SafeInvoke(...)才能訪問擴展方法。

+0

@Drew Noakes,現在跨線程沒有錯誤操作,但仍然沒有成果。它沒有讓我的形式前面。 – Anuya 2009-09-28 07:37:51

+0

@karthik - 如果你無法將表格轉到前面,請再次搜索一下(我確信這裏有很多關於這個的問題)。如果沒有幫助,請提出一個新問題。 – 2009-09-28 08:37:55