2016-02-01 34 views
1

我原以爲這是Single-Threaded Apartment機制,但this documentation表示只適用於COM對象。WinForms如何強制執行線程關聯?

有誰知道什麼機制 Windows窗體用來強制其線程親和力?

+1

這個問題可能是在我的頭上,但你所說的「強制執行其線程親和力」是什麼意思? – adv12

+0

@ adv12例如,假設您使用Application.Run(new Form1())'開始一個表單,並且該表單上有一個名爲'label1'的標籤。現在假設你啓動第二個線程。如果第二個線程試圖改變'label1.Text',你會得到一個錯誤。這就是所謂的「線程親和力」,你可以在這裏獲得更多信息:https://visualstudiomagazine.com/articles/2010/11/18/multithreading-in-winforms.aspx –

回答

4

TL; DR:它將當前調用的線程ID與用於創建控件的窗口句柄的線程ID進行比較。如果它們不同,則會引發異常。


如果你看看the reference source for Windows.Forms.Control你會發現一個屬性調用CheckForIllegalCrossThreadCalls

public static bool CheckForIllegalCrossThreadCalls { 
     get { return checkForIllegalCrossThreadCalls; } 
     set { checkForIllegalCrossThreadCalls = value; } 
    } 

每當一個句柄檢索這是用來:

public IntPtr Handle { 
     get { 
      if (checkForIllegalCrossThreadCalls && 
       !inCrossThreadSafeCall && 
       InvokeRequired) { 
       throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall, 
                   Name)); 
      } 

      if (!IsHandleCreated) 
      { 
       CreateHandle(); 
      } 

      return HandleInternal; 
     } 
    } 

因爲Handle被訪問的地方需要控制句柄,這是代碼檢查跨線程調用的合理位置。

它利用InvokeRequired屬性來查看何時會發生跨線程調用。

InvokedRequired本身有所涉及:

public bool InvokeRequired { 
     get { 

      using (new MultithreadSafeCallScope()) 
      { 
       HandleRef hwnd; 
       if (IsHandleCreated) { 
        hwnd = new HandleRef(this, Handle); 
       } 
       else { 
        Control marshalingControl = FindMarshalingControl(); 

        if (!marshalingControl.IsHandleCreated) { 
         return false; 
        } 

        hwnd = new HandleRef(marshalingControl, marshalingControl.Handle); 
       } 

       int pid; 
       int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(hwnd, out pid); 
       int currentThread = SafeNativeMethods.GetCurrentThreadId(); 
       return(hwndThread != currentThread); 
      } 
     } 
    } 
+0

好的寫作。 TL; DR-將當前調用的線程ID與用於創建窗口的線程ID進行比較。 –

+1

@AlexeiLevenkov我會無恥地偷走你的TL; DR –

+0

我想知道它是否是基礎控制類的一部分。非常感謝。 –