将所有者提供给从另一个线程调用的MessageBox

时间:2015-02-24 06:12:06

标签: c# multithreading winforms cefsharp

我在CefSharp 37中使用winforms。我已经实现了IRequestHandler,并希望在方法ResourceHandler中编写一些OnBeforeResourceLoad代码。

OnBeforeResourceLoad()中的

我检查了一些条件,并在此基础上显示带有“确定”和“取消”按钮的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,下一个代码也处于等待状态执行。我知道,因为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;

1 个答案:

答案 0 :(得分:3)

  

我检查了mainform的InvokeRequired,但仍然是它   抛出同样的例外。

您不仅需要检查InvokeRequired,还需要在GUI线程上调用。您可以使用MethodInvoker

来完成此操作

如果您使用MethodInvoker委托返回,则会从委托而不是MethodInvoker的方法返回。您可以将某个bool变量的值设置为true,您可以在委托完成其执行后使用该方法 return

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