我的程序中有一些链接,我必须逐个打开Web浏览器中的链接,并在网页中输入一些数据。
链接列表在GUI Thread中提供。但是我需要对主线程之外的链接做一些工作,以避免滞后和挂起GUI。我需要一个接一个地打开链接。我的意思是如果一个线程开始工作,下一个线程将仅在线程完成时启动。
关于链接列表的另一个重要事项是,当创建并运行线程时,链接列表正在更新。
所以我创建了一个工作线程来管理另一个Threads的启动。
我有两个AutoResetEvents
,一个用于检查列表是否为空(postInQueue
)。如果列表为空,则会等到链接添加到列表并调用postInQueue.set()
。
第二个是threadInProgress,当线程开始工作时,它等待线程调用threadInProgress.set()
;
AutoResetEvent threadInProgress = new AutoResetEvent(False);
AutoResetEvent postInQueue = new AutoResetEvent (False);
List<String> links = new List<String>;
public MainForm(){
InitializeComponent();
Thread threadManager = new Thread( () =>
{
while(true){
if (postsQueue.Count == 0)
postInQueue.WaitOne();
Thread t2 = new Thread(() => {
linkProcess(links[0]);
};
t2.SetApartmentState(ApartmentState.STA);
t2.Start();
threadInProgress.WaitOne(60000);
links.RemoveAt(0);
}
});
threadManager.start();
}
public void linkProcess(String link){
WebBrowser webBrowser = new WebBrowser();
webBrowser.DocumentCompleted += (s , e) => {
//Enter some data in webBrowser
Application.ExitThread();
threadInProgress.set();
};
webBrowser.Navigate(link);
Application.Run();
}
我必须在每个帖子中调用Application.Run()
DocumentCompleted
将调用事件。
此代码适用于两个或三个第一个链接但下一个线程将卡在Application.Run()
中,直到threadInProgress.WaitOne(60000);
发送超时。
两个第一个链接工作正常但后来我意识到CPU使用率为0%。当我点击全部中断时,我看到线程正在Application.Run()
。
有什么问题?
在一个论坛中,有人建议我使用除线程之外的进程......这怎么可能?会有帮助吗?
答案 0 :(得分:1)
所有这些线程都是疯狂的 - 尤其是调用线程然后调用Application.Run
来阻止线程退出的线程。这太过分了。
这是我要用的东西:
string uri = "https://www.mywebsite.com/customer/account/loginPost/";
string html;
using (var wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var nvc = new System.Collections.Specialized.NameValueCollection()
{
{ "form_key", "BaqsPklZGXt3Kq5o" },
{ "login[username]", "user@domain.com" },
{ "login[password]", "myfunkypassword" },
{ "send", "" },
};
byte[] result = wc.UploadValues(uri, nvc);
html = System.Text.Encoding.UTF8.GetString(result);
}
这可以像异步调用一样被包装,或者只是推送到普通的后台工作线程。在我尝试将其转换为方法之前,我想知道您正在尝试做什么 - 这意味着要查看您当前正在使用的代码。
您需要确定所需的名称 - 值对。我使用名为&#34; Request Maker&#34;的Chrome扩展程序。它在地址栏上放置一个小信封图标,您可以在页面上执行某些操作后单击该图标。它可以让您查看所做的请求并获取所有参数。
答案 1 :(得分:0)
这是以非常糟糕的方式构建的。通常,您有一个UI线程和一个Application.Run()
调用。如果要使用(例如)Invoke
向该线程显示新的UI表单,请在那里启动新表单。
这大大简化了一切。如果你这样做,很多线程和事件都会消失,你的问题就会消失。
Application.Run
应该阻止。毕竟它运行应用程序,直到该应用程序应该退出。通常,您会将表单传递给它。不确定您发布的代码是什么意思。 linkProcess
可能应该将浏览器控件放入表单中。没有表格,控件就不会出现在任何地方。
答案 2 :(得分:0)
好的......我在调用cbind(lm(d$Rate1~-1+d$Name)$coef,lm(d$Rate2~-1+d$Name)$coef)
> [,1] [,2]
>d$NameAira 16.33333 47.00000
>d$NameBen 31.33333 50.33333
>d$NameCat 44.66667 54.00000
时找不到挂机的原因。我搜索了互联网,我发现的所有问题都是关于Application.Run()
的一些问题,但是没有回答!
但至少我找到了一种在不使用Application.Run()
的情况下在另一个线程中使用WebBrowser.DocumentComplete
事件的方法!
我启动一个Application.Run()
的线程坚持,直到Application.Run()
事件将被调用并完成它才有效!
WebBrowser.DocumentComplete