【问题标题】:Too many threads - Impacting render performance线程过多 - 影响渲染性能
【发布时间】:2014-07-18 12:18:11
【问题描述】:

我有一个应用程序,它从 Web 获取大量信息并将其显示在带有 WPF 的窗口中。信息获取当然是在几个后台线程中完成的;它们中的大多数不应该是非常密集的计算(除了一些文本解析),而是主要依赖于获取网络内容(webclient.Download.. 和类似的)。

因为我必须发送很多请求,所以我启动了很多线程,否则用户将不得不等待数小时才能完成加载所有内容;由于其中许多线程主要等待来自网络的数据和/或开始对 Web 服务的新请求,因此理论上这应该不是问题。然而,在实践中,调度程序的性能通常比没有线程运行时要差得多。

后台线程由 TPL 数据流管道和 Parallel.ForEach 方法的混合创建。我也已经尝试通过指定 MaxThreads 来限制线程的数量,但是由于任何数据流块都可以启动 Parallel.Foreach 块,我认为这不太好用。

有没有其他方法可以提高调度程序的优先级、性能或减少卡顿?

编辑:任务/线程的数量通常在 50-100 之间,在最坏的情况下可能会更多。 weblookup 的一个典型场景是:向 webservice 发送请求,解析响应(

【问题讨论】:

  • 您是否在数据流块内的 ForEach 期间向 UI 发送更新(以显示进度等)?如果是这样,您可以尝试仅每 250 毫秒调度一次 UI。以前做过,效果很好:)
  • 我认为发布您的代码可以帮助确定您正在做的 CPU 与 IO 绑定工作量。
  • 当你说“线程太多”时,你能给我们估计一下你运行了多少线程吗?是10吗? 100? 1000? 10000?
  • @Tom 只在一个数据流块完成后,相隔几秒以上,后台线程应该是独立的
  • @YuvalItzchakov 代码不实用,但我添加了一个线程执行的典型场景。

标签: c# wpf multithreading


【解决方案1】:

考虑使用异步版本的下载函数,例如WebClient.DownloadDataTaskAsync,而不是启动一个新线程来下载数据。然后你不需要启动一个线程。只需调用

var result = await webClient.DownloadDataTaskAsync

并在await 之后处理结果。这将基本上启动下载操作并返回。下载完成后,将执行该方法的其余部分。最重要的是它不使用任何额外的线程。

【讨论】:

    【解决方案2】:

    由于没有代码示例,并且根据您帖子的语气,在我看来,您可以通过使用基于异步 IO 的模式完全节省使用 TPL DatablockParallel.ForEach 提供的线程的使用。

    如果您的主要目标是下载网络内容,我会尝试基于 Task Asynchronous Pattern 的方法。例如,这是使用HttpClient

    public async Task<string> DownloadWebContentAsync(string url)
    {
        var client = new HttpClient();
        // Assuming a GET request
        var response = await client.GetAsStringAsync(url);
    
        // Do some string processing..
    
        return response;
    }
    

    现在,吃吧:

    await DownloadWebContentAsync(url);
    

    【讨论】:

      【解决方案3】:

      我不清楚你的后台线程不会像你说的那样造成太多的 CPU 负载。即使平均而言它们造成的负载很小,负载也可能会激增并导致卡顿。

      尝试将后台工作放在优先级较低的TaskScheduler 上。 Parallel Extension Extras 有一个支持该功能的 TaskScheduler

      您多久更新一次用户界面?也许是太频繁了。限制更新频率。

      我们到底在谈论多少个线程?如果数量达到数百个,请考虑使用异步 IO。异步 IO 操作在运行时不使用线程。甚至没有后台线程。

      【讨论】:

      • 我的所有四个内核的 CPU 利用率都保持在 30-60% 之间。 UI 有一些非常丑陋的计算和效果,对性能有相当大的影响,但在后台没有线程运行的情况下,它似乎运行顺畅;由于需要所有效果和动画,因此也很难优化。我一定会尝试使用异步和任务调度程序,谢谢!
      猜你喜欢
      • 1970-01-01
      • 2021-12-23
      • 2013-01-30
      • 2011-06-18
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-08
      相关资源
      最近更新 更多