应用程序运行 () 导致挂起程序
本文关键字:挂起 程序 运行 应用程序 | 更新日期: 2023-09-27 18:32:43
>我的程序中有一些链接,我必须在Web浏览器中逐个打开链接并在网页中输入一些数据。
链接列表在 GUI 线程中提供。但是我需要在主线程之外使用链接进行一些工作,以避免滞后和挂起 GUI。我需要一个接一个地打开链接。我的意思是,如果一个线程开始工作,下一个线程只有在线程完成工作时才开始。
关于链接列表的另一个重要事情是,当线程创建并工作时,链接列表正在更新。
所以我创建了一个工作线程来管理另一个线程的启动。
我有两个AutoResetEvents
,一个用于检查是否为空的列表(postInQueue
(。如果列表为空,则等待链接添加到列表中并调用postInQueue.set()
。
第二个是线程进行中,当线程开始工作时,它会等到线程调用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()
中。
问题出在哪里?
在论坛中,有人建议我使用线程以外的进程...这怎么可能?会有帮助吗?
线程的东西都是疯狂的 - 尤其是调用线程然后调用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);
}
这一切都可以包装为异步调用,或者只是推送到正常的后台工作线程。在我尝试将其转换为方法之前,我想知道您正在尝试做什么 - 这意味着查看您当前使用的代码。
您需要弄清楚您需要哪些名称-值对。我使用一个名为"Request Maker"的Chrome扩展程序。它在地址栏上放置了一个小信封图标,您可以在页面上执行某些操作后单击该图标。它使您可以查看发出的请求并获取所有参数。
这是以非常糟糕的方式构建的。通常,您有一个 UI 线程和一个对 Application.Run()
的调用。如果要显示新的 UI 窗体,请使用(例如(Invoke
调用该线程,然后在那里启动新窗体。
这大大简化了一切。如果你这样做,很多线程和事件就会消失,你的问题在这个过程中消失了。
Application.Run
应该阻止。毕竟,它会运行应用程序,直到应用程序应该退出。通常,您会向其传递表单。不确定您的意图是发布的代码。 linkProcess
可能应该将浏览器控件放入窗体中。如果没有窗体,控件就无法出现在任何地方。
好的...打电话给Application.Run()
时找不到挂的原因.我在网上搜索,我发现的只是一些关于不同场景Application.Run()
的问题,但没有答案!
但至少我找到了一种在另一个线程中使用WebBrowser.DocumentComplete
事件而不使用 Application.Run()
的方法!
我启动一个线程坚持运行Application.Run()
直到WebBrowser.DocumentComplete
事件将被调用并完成它的工作!
Thread t1 = new Thread ( () => {
AutoResetEvent keepMeAlive = new AutoResetEvent( False );
webBrowser1.DocumentComplete += (s , e) => {
//Do Some Stuff
keepMeAlive.set();
};
webBrowser1.Navigate("www.google.com");
Thread keepAlive = new Thread ( () =>{
keepMeAlive.WaitOne();
});
keepAlive.Start();
});