Application.Run()导致挂起程序

时间:2016-01-31 21:19:06

标签: c# multithreading

我的程序中有一些链接,我必须逐个打开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()

有什么问题?

在一个论坛中,有人建议我使用除线程之外的进程......这怎么可能?会有帮助吗?

3 个答案:

答案 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