C# StaTaskScheduler(TPL扩展)和WebBrowser控制WPF-线程错误
我想在后台下载一个带有WebBrowser控件(WPF)的网站,然后解析该网站。下载应该是一个“紧密循环”。我只需要源代码作为字符串。我用下面的代码进行了尝试,但没有给出结果。 如果我不将它与StaTaskScheduler一起使用,程序在循环过程中似乎会释放。 有什么想法吗 多谢各位C# StaTaskScheduler(TPL扩展)和WebBrowser控制WPF-线程错误,c#,wpf,multithreading,task-parallel-library,C#,Wpf,Multithreading,Task Parallel Library,我想在后台下载一个带有WebBrowser控件(WPF)的网站,然后解析该网站。下载应该是一个“紧密循环”。我只需要源代码作为字符串。我用下面的代码进行了尝试,但没有给出结果。 如果我不将它与StaTaskScheduler一起使用,程序在循环过程中似乎会释放。 有什么想法吗 多谢各位 StaTaskScheduler sta = new StaTaskScheduler(numberOfThreads: 1); private void Button1_Click(object sender
StaTaskScheduler sta = new StaTaskScheduler(numberOfThreads: 1);
private void Button1_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 2; i++)
{
Task.Factory.StartNew(() =>
{
WebBrowser wb3 = new WebBrowser();
wb3.Source = new Uri("MyURL");
n++;
wb3.LoadCompleted += new LoadCompletedEventHandler(wb_LoadCompleted);
}, CancellationToken.None, TaskCreationOptions.None, sta);
}
}
void wb_LoadCompleted(object sender, NavigationEventArgs e)
{
WebBrowser w = sender as WebBrowser;
HtmlDocument document = new HtmlDocument(w.Document);
blockingCollection.Add(document.Body.OuterHtml);
Task.Factory.StartNew(
() =>
{
while (!blockingCollection.IsCompleted)
{
string dlcode;
Thread.Sleep(500);
if (blockingCollection.TryTake(out dlcode))
{
// tb is a TextBox
Dispatcher.BeginInvoke(new Action(() => { tb.Text = dlcode; }));
}
}
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
StaTaskScheduler sta=新的StaTaskScheduler(numberOfThreads:1);
私有无效按钮1\u单击(对象发送者,路由目标)
{
对于(int i=0;i<2;i++)
{
Task.Factory.StartNew(()=>
{
WebBrowser wb3=新的WebBrowser();
wb3.Source=新Uri(“MyURL”);
n++;
wb3.LoadCompleted+=新的LoadCompletedEventHandler(wb_LoadCompleted);
},CancellationToken.None,TaskCreationOptions.None,sta);
}
}
无效wb_加载已完成(对象发送方,导航目标e)
{
WebBrowser w=发送方作为WebBrowser;
HtmlDocument document=新HtmlDocument(w.document);
blockingCollection.Add(document.Body.OuterHtml);
Task.Factory.StartNew(
() =>
{
而(!blockingCollection.IsCompleted)
{
字符串dlcode;
睡眠(500);
if(blockingCollection.TryTake(out dlcode))
{
//tb是一个文本框
Dispatcher.BeginInvoke(新操作(()=>{tb.Text=dlcode;}));
}
}
},CancellationToken.None,TaskCreationOptions.None,TaskScheduler.Default);
}我建议不要使用
WebBrowser
,而是直接使用WebClient
。最简单的方法是制作一个例程,将下载数据包装到任务中:
Task<string> DownloadStringAsync(Uri address)
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
WebClient client = new WebClient();
// Note that you can add error checking here by looking at e.Error/etc, and setting the cancel/error in tcs appropriately...
client.DownloadStringCompleted += (o,e) => tcs.SetResult(e.Result);
client.DownloadStringAsync(address);
return tcs.Task;
}
任务下载StringAsync(Uri地址)
{
TaskCompletionSource tcs=新的TaskCompletionSource();
WebClient客户端=新的WebClient();
//请注意,您可以通过查看e.error/etc并在tcs中适当设置cancel/error来在此处添加错误检查。。。
client.DownloadStringCompleted+=(o,e)=>tcs.SetResult(e.Result);
client.DownloadStringAsync(地址);
返回tcs.Task;
}
这样,您就可以直接使用这些任务,并在完成时将其结果设置到BC中。这将比尝试旋转一个
WebBrowser
控件要简单得多,该控件用于视觉用途。Reed是正确的。WebBrowser具有与UI线程交互的可视元素,即使您没有显示它。感谢您的回答,但问题是我的网站是一个ASP.NET网站,动态加载内容,如果我使用普通Http请求,我会得到没有内容的空字符串。对不起,我忘了提这件事。这就是为什么我想使用这个解决方案。然而,我也需要一个快速的解决方案。对我来说,这相当缓慢。如果你有别的办法解决这个问题,我会很高兴的。我现在不知所措:(是否可以使用MSHMTLO之类的工具来完整下载网站并以字符串形式返回源代码。这意味着使用“引擎来解释网站”不显示它?@user774326:您不应该得到一个空字符串-您应该至少得到一些类型的标题信息。尝试使用WebRequest
获取数据,并检查返回的标题……我的意思是,我得到了一个字符串,但缺少的是一个包含信息的整个表。信息是仅在启用JavaScript时显示。如果禁用JavaScript,则重要信息将再次丢失。很抱歉,我在上一篇文章中没有对其进行充分解释,但现在是晚上1:30。