2015-02-24 25 views
1

我在winforms中使用CefSharp 37。我已经实现了IRequestHandler,并且想要在方法OnBeforeResourceLoad中编写一些ResourceHandler代码。给所有者MessageBox从另一个线程调用

in OnBeforeResourceLoad()我检查一些条件,并在此基础上显示一个带有OK和Cancel按钮的MessageBox。按Cancel我想返回true,否则返回false。代码如下:

public bool OnBeforeResourceLoad(IWebBrowser browser, IRequest request, IResponse response) 
    {    
      if (!request.Url.Contains(ContentHelper.requestTrapKey) 
      {      
       var handler = browser.ResourceHandler; 
       if (handler != null) 
       { 
        handler.RegisterHandler(request.Url, ResourceHandler.FromStream(File.OpenRead(ContentHelper.contentRootPath), Path.GetExtension(ContentHelper.contentRootPath + final));       
       } 
      } 
      else if (!request.Url.Contains(ContentHelper.requestTrapKey + "course") && request.Url.Contains(ContentHelper.requestTrapKey)) 
      {      
       if (MessageBox.Show("message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel) 
       { 
        return true; 
       }     
      } 

     return false; 
    } 

据观察,有时MessageBox()去背后的主要形式和用户等待消息框也来和旁边还码在等待状态来执行。我知道,因为MessageBox.Show()在主线程之外的其他线程上调用,所以这就是为什么它会落后。

那么有没有什么办法可以向用户展示MessageBox或给用户一条消息,而不必将其放在后面并从用户那里接受输入,并相应地返回true或false来加载资源。

更新

我尝试作为@Adil回答说:通过MethodInvoker包裹代码,然后MessageBox停留在形式的顶部,但作为当我按在消息框中应用程序的任何按钮,得到忌用。

我写MyRequestHandler类的参数化的构造函数:

public MyRequestHandler(MainForm mainform) 
    { 
     this.mainform = mainform; 
    } 

然后由@Adil说:

bool returnValue = false; 
mainform.Invoke((MethodInvoker)(() => 
{ 
    if (MessageBox.Show(mainform,"message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel) 
    { 
     returnValue = true; 
    } 
})); 
return returnValue; 

回答

3

我系有检查的MainForm的InvokeRequired但仍然是 抛出同样的异常。

您不仅需要检查InvokeRequired,但需要在GUI线程上调用。你可以使用MethodInvoker来做到这一点。

如果您有MethodInvoker委托人的退货,它将从代理人而不是具有MethodInvoker的方法返回。您可以将某个布尔变量的值设置为true,您可以在委托完成其执行后使用返回

bool returnValue = false; 
mainform.Invoke((MethodInvoker)(() => 
{ 
    if (MessageBox.Show(mainform,"message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel) 
    { 
     returnValue = true; 
    } 
})); 
return returnValue; 
+0

是否有必要将此代码保存在'if'中,以检查'mainform.InvokeRequired'? – Amogh 2015-02-24 10:34:54

+0

它不是必须的,但如果你这样做,你将得到很少的性能好处,因为如果InvokeRequired是假的,你将有更少的代码执行。 – Adil 2015-02-24 10:38:53

+0

好吧我用'if'包围了代码,但是我观察到3-2'MessageBox'应用程序被挂起后,为什么?如果我从'MessageBox'中删除所有者对象(mainform),那么所有工作都可以正常工作,但有时MessageBox会返回到主窗口,因为在其他线程上调用MessageBox.Show()。 – Amogh 2015-02-24 11:05:51

相关问题