【问题标题】:Getting Cross-thread operation not valid in SetWindowPos()在 SetWindowPos() 中获取无效的跨线程操作
【发布时间】:2010-12-01 22:18:36
【问题描述】:

我正在尝试从与创建表单的线程不同的线程访问表单,最后出现错误:

跨线程操作无效

代码:

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

我正在传递一个在另一个线程中运行的表单。我试过测试InvokeRequired,但总是假的。

我是线程新手。

【问题讨论】:

标签: c# .net winforms multithreading exception-handling


【解决方案1】:

确保您正在为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(...) 才能访问扩展方法。

【讨论】:

  • @Drew Noakes,现在跨线程操作没有错误,但仍然没有结果。它没有让我的表格出现在前面。
  • @karthik - 如果您无法将表格放在前面,请再次搜索 SO(我相信这里有很多关于此的问题)。如果这没有帮助,请提出一个新问题。
猜你喜欢
  • 2010-12-04
  • 1970-01-01
  • 2023-03-15
  • 2011-07-11
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多