本来以为是单线程单元机制,结果this documentation表示仅适用于 COM 对象。
有谁知道 Windows 窗体使用什么机制来强制其线程关联?
最佳答案
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);
}
}
}
关于c# - WinForms 如何强制执行线程亲和性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35139910/