错误:使用 CefSharp 使用 Form.close() 时"Cross-thread operation not valid"



I use Cefsharp.Winform (http://cefsharp.github.io/(. 我尝试 Form.Close(( 但它错误: System.InvalidOperationException:"跨线程操作无效:控制'Form2'是从创建它的线程以外的线程访问的。

表格1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TEST_CEF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
}
}
}

表单2.cs

using CefSharp;
using CefSharp.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TEST_CEF
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
InitBrowser();
}
public ChromiumWebBrowser browser;
public void InitBrowser()
{
Cef.Initialize(new CefSettings());
browser = new ChromiumWebBrowser("www.google.com");
this.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
browser.FrameLoadEnd += WebBrowserFrameLoadEnded;
}
private void WebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
if (browser.Address.IndexOf("google") > -1)
{
timer1.Start();
}
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
browser.Dispose();
Cef.Shutdown();
}
int time = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if (time==3)
{
this.Close();
}
}
}
}

你使用哪种计时器? 请考虑在 timer1_Tick 方法中使用 InvokeRequired。

private void timer1_Tick(object sender, EventArgs e)
{
if (InvokeRequired) { Invoke(new Action(() => { timer1_Tick(sender, e); })); return; }
time++;
if (time==3)
{
this.Close();
}
}

来自文档(我的强调(:

请务必注意,此事件是在 CEF UI 线程上触发的,默认情况下,该线程与应用程序 UI 线程不同。阻止此线程任何时间长度都是不明智的,因为您的浏览器将变得无响应和/或挂起。若要访问 UI 元素,需要调用/调度到 UI 线程。

因此,您在另一个线程中启动计时器,因此我想Tick事件也将在此CEF UI线程中引发。

因此,如果需要,您必须使用Invoke

Action close = () => this.Close();
if (InvokeRequired)
Invoke(close);
else
close();

最新更新