我使用Cefsharp.Winform(http://cefsharp.github.io/)。 我尝试Form.Close()但它错误: System.InvalidOperationException:'跨线程操作无效:控制'Form2'从其创建的线程以外的线程访问。'
Form1.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();
}
}
}
Form2.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();
}
}
}
}
答案 0 :(得分:0)
您使用哪种计时器? 考虑在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();
}
}
答案 1 :(得分:0)
来自docs(强调我):
值得注意的是,此事件是在CEF UI线程上触发的,该线程默认情况下与应用程序UI线程不同。阻止此线程持续任何时间是不明智的,因为您的浏览器将无响应和/或挂起.. 要访问UI元素,您需要调用/分发到UI线程。
所以你在另一个线程中启动计时器,所以我想在这个CEF UI线程中也会引发Tick
事件。
因此,如果需要,您必须使用Invoke
:
Action close = () => this.Close();
if (InvokeRequired)
Invoke(close);
else
close();