获取跨线程操作SetWindowPos()无效

获取跨线程操作SetWindowPos()无效

问题描述:

我试图从不同的线程访问的形式来其上的形式被创造了,终于结束了一个错误:获取跨线程操作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

确保您正在测试正确的对象为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