应用程序运行 () 导致挂起程序

本文关键字:挂起 程序 运行 应用程序 | 更新日期: 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();
});