非ui线程可以阻止ui线程吗?导致它冻结并变得反应迟钝?

时间:2015-01-15 16:56:56

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

好吧,就我从线程中读到的而言,这是不可能的,但在我的情况下肯定会发生。

取决于我开始执行多少后台任务,即使它们与ui线程有0关系,也肯定会影响我的gui响应

所以我的问题是,是否有人知道其他线程如何让ui变得反应迟钝?

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

这是我的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();

3 个答案:

答案 0 :(得分:7)

您的计算机无法同时运行无限数量的线程。它实际上只能实际运行一些。然后它需要在各个线程中旋转,为每个线程提供一小部分时间,以便更大程度地“伪造”并行化。

你拥有的线程越多,每个人获得的馅饼就越小。如果你有足够的线程,你最终会得到“饥饿”,每个线程都有这么短的时间,以至于无法做任何有效的事情,整个机器就会陷入停滞状态。切换线程的成本加剧了这一点;一台机器可以达到最终花费大部分时间在线程之间切换的程度,而不是做有成效的工作。

为了防止这种情况,您应该将创建的线程数限制为相当小的数量。如果您依赖于线程池,那么它的调度程序通常可以有效地创建比在您的机器上有效的更多线程。

答案 1 :(得分:1)

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

你怎么能这样做:

  • 运行至少{CPU核心数}的CPU负载过重的线程
  • 运行一些内存密集的线程/进程 - 触及很多独特的内存(即几千Kb的字节)应该这样做
  • 具有随机I / O的垃圾磁盘,磁盘I / O本身可能不足以正确减慢UI线程。

答案 2 :(得分:1)

这里的技术之一是将UI和长时间运行的内容分成单独的进程,这样他们就不会干涉。

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

您也可以尝试使用不同的GC模式,例如并发,背景..并查看它们如何影响性能。

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

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