private void HideOperationAsync()
{
while (!this.IsHandleCreated)
{
}
browser = new WebBrowser();
Task t = new Task(() => {
browser.Invoke(new Action(() => {
browser.DocumentCompleted += webBrowser1_DocumentCompleted;
browser.Url = new Uri("http://huaban.com/pins/267054525/zoom/");
MessageBox.Show("not on show");
}));
});
t.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
HideOperationAsync();
}
============
以上是源码,我知道 通过SynchronizationContext可以轻松实现非UI线程操作控件的但上面的这个代码为什么不可以,提示的错误信息是“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”,while (!this.IsHandleCreated)不能再获取到窗口句柄之前通过,这里不对吗?
这个代码是测试简单功能用的,无所谓什么功能,就是程序一运行就用另外一个线程操作控件。
同步操作的代码没有问题:
WebBrowser browser = null;
private void HideOperation()
{
browser = new WebBrowser();
browser.DocumentCompleted += webBrowser1_DocumentCompleted;
browser.Url = new Uri("http://huaban.com/pins/267054525/zoom/");
MessageBox.Show("not on show");
}
你只是实例化了WebBrowser,而未添加到窗体上
为什么我同步执行操作WebBrowser的代码时不用加到窗体上,而异步的时候需要?
@北在北方: 请查找下browser的引用,看是否有××.Controls.Add(browser)类似的代码,因为如果你只是实例化的话并不会Create Handle,也没有跨线程,这里你可以把Invoke调用去掉后重新生成运行
@jello chen: 我不从了同步操作的代码,也是仅仅new一个WebBrowser,没有添加到窗体,但是没像异步那样出错。
@北在北方: 是没出错,但是界面上并没有browser,也就看不到你所指定的uri的内容
@jello chen:忘了说目的了,我是为了获取网页的源码,因为有部分源码是js加载的,但WebClient获取的源码没有包含js运行后加载的部分,所以我用了WebBrowser,因为WebBrowser支持js,所以并不需要肉眼看到WebBrowser加载的内容,所以同步代码里,并没有添加到窗体上。
@北在北方: 那应该不会有跨UI线程的问题
你Invoke,Browser但是并没有使用的并非invoke中的对象。你应该像下面这样。
this.Invoke(new Action<Browser>(p=>
{
p.XXX....省略部分代码。
}), browser);