【问题标题】:Threading Web requests handled in Main?在 Main 中处理 Web 请求的线程?
【发布时间】:2009-11-24 20:28:41
【问题描述】:

我正在用 C# 编写一个应用程序,并且我正在创建多个 BackgroundWorker 线程以从网页中获取信息。尽管他们是 BackgroundWorkers,但我的 GUI 表单变得没有响应。

我在调试的时候,程序无响应的时候就暂停了,可以看到我在主线程中,在网页抓取方法上暂停了。不过,这个方法只能从新线程中调用,所以我不知道为什么我会出现在主线程中。

这有意义吗?我该怎么做才能确保 Web 请求仅在各自的线程中处理?

编辑:一些代码和解释

我正在处理大量地址列表。每个线程将处理一个或多个地址。我可以选择我想创建多少线程(我保持谦虚:))

//in “Controller” class
public void process()
{
for (int i = 1; i <= addressList.Count && i<= numthreads; i++) 
            {
                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += doWork;
                bw.RunWorkerAsync((object)i);
            }
}

public void doWork(object sender, DoWorkEventArgs e)
{
    //create an object that has the web fetching method, call it WorkObject
    //WorkObject keeps a reference to Controller. 
    //When it is done getting information, it will send it to Controller to print
    //generate a smaller list of addresses to work on, using e.Argument (should be 'i' from the above 'for' loop)
    WorkObject.workingMethod()
}

创建 WorkObject 时,它使用“i”来知道它是什么线程号。它将使用它来获取要从中获取信息的网址列表(从主窗体、控制器和每个工作对象共享的较大地址列表中获取信息——每个线程将处理较小的地址列表)。当它遍历列表时,它将调用“getWebInfo”方法。

//in “WorkObject” class
public static WebRequest request;

public void workingMethod()
{
    //iterate over the small list of addresses. For each one, 
        getWebInfo(address)
        //process the info a bit...then
        myController.print()

//note that this isn’t a simple “for” loop, it involves event handlers and threading 
//Timers to make sure one is done before going on to the next
}

public string getWebInfo (string address)
{
    request = WebRequest.Create(address);
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string content = reader.ReadToEnd();
                return content;
}

【问题讨论】:

  • 你能发布一些代码吗?启动线程和请求的代码
  • 好的。希望这是足够的/不是太多的信息。

标签: c# multithreading webrequest


【解决方案1】:

您应该在 BackgroundWorker 的 DoWork 事件中执行所有网络工作,是吗?

一些剪辑的代码可以帮助我们理解发生了什么。

【讨论】:

  • 好的,编辑了帖子 - 添加了一些代码。希望这是足够的信息
【解决方案2】:

在类似的情况下,我发现我可以通过创建自己的线程(没有 BackgroundWorker 和没有 ThreadPool)并限制活动连接的数量来更好地控制。将 IP 地址写入 Queue,然后选择每个,将其传递给辅助类,您可以在新线程上调用它的 DoSomething 方法。通过在启动线程时增加计数器并在线程完成时减少计数器来进行节流。您可以使用帮助程序类中的回调例程来通知您的 UI 线程以更新界面或指示线程已完成。

使用您的 UI 更改油门限制并观察任务管理器以查看对内存和 CPU 使用率的影响。您可以在 app.config 中添加 maxconnection 设置以获得更多同时连接。

【讨论】:

  • 最初,我正在创建自己的线程,但这导致 UI 挂起,因此我决定尝试 BackgroundWorkers。仍然有同样的问题。 CPU 使用率和内存使用率通常非常低 - 除非我告诉它一次创建一堆线程,但一旦它们开始运行它就会消失。
【解决方案3】:

我无法弄清楚为什么后台工作人员会导致挂起,但我没有使用同步 HTTP 请求,而是使用本指南切换到异步:

http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/

清除所有的挂起。感谢您的回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2014-11-16
    • 2021-04-09
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    相关资源
    最近更新 更多