c# - WinForms 如何强制执行线程亲和性?

标签 c# multithreading winforms

本来以为是单线程单元机制,结果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/

相关文章:

c# - 通过事件进行线程更新主屏幕

c# - openxml sdk excel文件打开关闭公式单元格在windows azure网站上重新计算

arrays - 创建数组时使用 OpenMP 时出现段错误

iphone - 多线程如何在 iPhone 上的 Objective-C 中工作?

c# - 从文件中删除 ListView 中的项目 C#

c# - IEnumerable.ElementAt - 值存在时参数超出范围异常

java - 多线程Java小程序弹跳球

c# - SQL Server Express,不能在C#中读取或写入

c# - 我如何按下控制

c# - 自动调整winform中的控件大小