【问题标题】:Can a non ui thread block ui thread? cause it to freeze and become unresponsive?非ui线程可以阻塞ui线程吗?导致它冻结并变得无响应?
【发布时间】:2015-01-16 07:56:01
【问题描述】:

好吧,据我从这里的线程中读取,这是不可能的,但在我的情况下肯定会发生。

根据我启动的后台任务的数量,肯定会影响我的 gui 响应能力,即使它们与 ui 线程的关系为 0

所以我的问题是有人知道其他线程如何使 ui 变得无响应吗?

我 100% 确定这些非 ui 线程会导致其运行缓慢,因为即使我禁用所有 gui 更新事件也会发生这种情况。在我的情况下,它肯定会受到多少线程的影响(抓取 urls 任务和处理这些抓取的页面任务)我开始

这是我的 ui 线程以及我如何启动后台任务:

InitializeComponent();

this.DataContext = this;

ThreadPool.SetMaxThreads(10000, 10000);
ThreadPool.SetMinThreads(10000, 10000);

PublicVariables.initPublicVariables();

PublicStaticFunctions.func_initLists();
PublicSettings.func_init_Settings_Messages();

Task.Factory.StartNew(() =>
{
    CheckCrawlURLs.func_StartCrawlingWaitingUrls();
    AddUrlsToDB.func_StartUrlAddProcess();
    LoadCrawlingUrlsFromDatabase.func_StartLoadingUrlsFromDB();
    GlobalStats.startUpdatingGlobalStatValues();
    PagesProcessor.func_StartProcessingWaitingPages();                    
}, CancellationToken.None, 
   TaskCreationOptions.LongRunning, 
   TaskScheduler.Default);

AppDomain currentDomain = AppDomain.CurrentDomain;
Application.Current.DispatcherUnhandledException += 
     new DispatcherUnhandledExceptionEventHandler(CloseCrashHandlers.AppDispatcherUnhandledException);

currentDomain.UnhandledException += 
     new UnhandledExceptionEventHandler(CloseCrashHandlers.CrashCloseHandler);

Closing += new CancelEventHandler(CloseCrashHandlers.CloseHander);

set_Buttons_Status();

_timer = new Timer(updateGlobalStatistics, 
                    null, 
                    PublicSettings.irTimers_Delayed_Start_MiliSeconds, 
                    PublicSettings.ir_RefreshUI_MS);

WebConnectionStats.Init();

【问题讨论】:

  • 只是不要使用太多线程。 This answer 可能会有所帮助。
  • @Clemens 是的,可以解决问题,但我想知道一些事情。我有充足的 CPU 功率、内存和硬盘驱动器速度。所以我希望我的软件吸走我所有的资源,但它肯定会杀死用户界面。应用程序工作正常。

标签: c# wpf multithreading task-parallel-library windows-8.1


【解决方案1】:

您的机器无法同时运行无限数量的线程。它实际上一次只能运行几个。然后它需要在各个线程之间轮换,给它们每个小块时间,以便在更大程度上“伪造”并行化。

你拥有的线程越多,每个人得到的馅饼就越小。如果你有足够多的线程,你最终会“饿死”,每个线程的时间都很短,以至于它不能做任何有成效的事情,整个机器就会停止。切换线程需要成本这一事实加剧了这种情况。机器可能会最终花费大部分时间在线程之间切换,而不是进行生产性工作。

为防止这种情况,您应该将创建的线程数限制在一个相当小的数量内。如果您依赖线程池,它的调度程序通常不会创建比在您的机器上有效的线程更多的线程。

【讨论】:

  • 感谢我自己限制了每个任务的数量。我的意思是有多少将同时运行。所以这可能仅仅是因为我开始的任务数量?但是我的 CPU 远未达到 100%。这就是为什么我想推动更多但是即使应用程序运行正确,ui也会变得无响应。
  • 通过线程切换消耗所有 CPU 资源确实是个好主意 - 我的理解是,速度慢的原因是有更多线程计划运行并且每个线程的运行频率较低,而不是时间片本身变成太短了(我认为切片时间有下限......我猜需要研究)。
  • Servy 我将垃圾收集器模式更改为服务器模式,它取得了巨大的进步你说什么:D
  • @MonsterMMORPG 我会说显然你正在创建大量的长寿命对象,因此 GC 花费了大量时间运行,因为它需要停止执行所有其他线程它运行。
【解决方案2】:

UI 响应受到整体机器负载的严重影响。将 CPU/内存使用率推向 100% 几乎可以保证 UI 的缓慢性。

你怎么能这样做:

  • 至少运行 {number of CPU cores} 个 CPU 负载较重的线程
  • 运行一些内存密集型线程/进程 - 接触许多独特的内存块(即相隔几 Kb 的字节)应该这样做
  • 具有随机 I/O 的垃圾磁盘以及磁盘 I/O 本身可能不足以适当地减慢 UI 线程。

【讨论】:

  • 感谢好的建议,但我的 CPU 远不是 100%,我的内存和硬盘也是如此。这就是为什么我想解决这个问题来推动我的计算机限制。即使随着任务数量的增加 ui 变得无响应,它也会继续按预期运行。
  • Alex 我将垃圾收集器模式更改为服务器模式,它取得了巨大的进步你说什么:D
  • @MonsterMMORPG Server GC 不需要等待所有线程在托管代码中停止,据我所知 - 所以如果你有大量线程,它确实会更快。如果您使用同步 Web 请求,那么大多数线程会卡在本机代码中等待响应,从而使 GC 等待更慢。
  • "如果你使用同步 web 请求,那么大多数线程会卡在本机代码中等待响应,从而使 GC 等待更慢。-"你能解释一下吗,因为我无法理解它 ty跨度>
  • @MonsterMMORPG GC 需要在“安全的 GC”状态下停止线程。在本机代码中等待可能会阻止 GC 停止线程,因为它可能是“不安全的”......这里的搜索带来了一些好文章 - bing.com/… - 即 dotnet.dzone.com/news/garbage-collection-threadinformit.com/articles/article.aspx?p=1409801&seqNum=2跨度>
【解决方案3】:

这里的技术之一是将 UI 和长时间运行的东西真正分离到单独的进程中,这样它们就不会干扰。

垃圾收集器很可能会暂停所有线程来清理堆,因此您会遇到延迟。

您也可以尝试使用不同的 GC 模式,例如并发、后台……看看它们如何影响性能。

也可以提高 UI 线程的优先级,降低其他工作线程的优先级,虽然有点不清楚为什么你有这么多线程。

http://msdn.microsoft.com/en-us/library/0xy59wtx%28v=vs.110%29.aspx

【讨论】:

  • 现在这些是一些可靠的建议。你能详细说明一下吗?如何分离进程?正如你所说,GB 也几乎可以影响这一点,也是我怀疑的事情之一。以及如何设置不同的 gb 模式?非常非常。如果单独的进程线程之间的通信也会丢失?看起来不可能。
  • 我更改为服务器版本,似乎产生了巨大的影响:D
  • 我想默认 GC 不是 wpc 应用程序的服务器版本吧?
猜你喜欢
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多