0

Alright as far as I read from threads here it is not possible but in my case definitely happening.

Depending on how many background tasks I do start definitely effects my gui responsiveness even though they have 0 relation to ui thread

So my question is do anybody have any idea how other threads can make ui become unresponsive ?

I am 100% sure that these non ui threads causing its slowness because it happens even when i disable all gui update events. And it definitely effected by how many threads in my case (crawling urls tasks and processing these crawled pages tasks) I start

Here is my ui thread and how I start background tasks:

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();
svick
  • 236,525
  • 50
  • 385
  • 514
Furkan Gözükara
  • 22,964
  • 77
  • 205
  • 342
  • Just don't use too many thread. [This answer](http://stackoverflow.com/a/2044198/1136211) may be helpful. – Clemens Jan 15 '15 at 17:04
  • @Clemens yes that solves problem however i wonder something. I have plenty of cpu power, ram and harddrive speed. So i want my software to suck all my resources however it definitely kills ui. Application works fine though. – Furkan Gözükara Jan 15 '15 at 17:06

3 Answers3

7

Your machine can't run an infinite number of threads all at the same time. It can only ever actually run a few at once. It then needs to rotate through the various threads, giving them each a small chunk of time, in order to "fake" parallelization to a greater degree.

The more threads you have, the smaller piece of the pie each one gets. If you have enough threads you end up getting "starvation", where each thread gets so little time that it can't do anything productive, and the whole machine just crawls to a halt. This is exacerbated by the fact that there is a cost to switching threads; a machine can get to the point where it ends up spending most all of its time just switching between threads, rather than doing productive work.

To prevent this you should limit the number of threads you create to a fairly small number. If you rely on the thread pool, its scheduler will generally be effective at not creating more threads than would be efficient on your machine.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • thanks i am limiting each number of tasks myself. I mean how many will run concurrently. So this may be merely because of number tasks i start ? however my cpu is far from 100%. that is why i want to push more however ui becomes unresponsive even though application runs correctly. – Furkan Gözükara Jan 15 '15 at 17:10
  • Eating all CPU resources with thread switching is indeed good idea - my understanding is that slowness comes from the fact that there are more threads scheduled to run and each runs less frequently rather than slices of the time themselves becomes too short (I think there is lower limit of slice time... need to study that I guess). – Alexei Levenkov Jan 15 '15 at 17:31
  • Servy i changed garbage collector mode to server mode and it made huge improvement what do you say :D – Furkan Gözükara Jan 15 '15 at 18:57
  • @MonsterMMORPG I would say that apparently you were creating a huge number of long lived objects, and thus the GC was spending a huge amount of time running, as it needs to stop execution of all other threads when it runs. – Servy Jan 15 '15 at 18:59
1

UI responsiveness is heavily impacted by overall machine load. Pushing CPU/memory usage toward 100% will pretty much guarantee slowness of UI.

How can you do that:

  • run at least {number of CPU cores} of threads with heavy CPU load
  • run some memory intensive thread/process - touching a lot of unique pieces of memory (i.e. bytes several Kb apart) should do that
  • trash disk with random I/O, also disk I/O by itself may not be enough to properly slow down UI thread.
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • thanks good suggestions but my cpu is far from being 100% also my ram and harddisk as well. That is why i want to solve this problem to push my computer limits. Even if ui becomes un responsive as number of tasks increases, it continue to operate as expected. – Furkan Gözükara Jan 15 '15 at 17:08
  • Alex i changed garbage collector mode to server mode and it made huge improvement what do you say :D – Furkan Gözükara Jan 15 '15 at 18:56
  • @MonsterMMORPG Server GC does not need to wait for all threads to stop in managed code as far as I know - so if you have huge number of threads indeed it will be faster. If you use synchronous web requests than most threads would be stuck in native code waiting for response making GC wait even slower. – Alexei Levenkov Jan 15 '15 at 19:00
  • "If you use synchronous web requests than most threads would be stuck in native code waiting for response making GC wait even slower. – " can you explain this more because i couldn't understand it ty – Furkan Gözükara Jan 15 '15 at 19:38
  • @MonsterMMORPG GC needs threads to be stopped in "safe for GC" state. Waiting in native code *may* prevent GC from stopping thread as it could be "unsafe"... Here is search that brings some good articles - http://www.bing.com/search?q=.net+garbage+collection+freeze+thread+internals - i.e. http://dotnet.dzone.com/news/garbage-collection-thread and http://www.informit.com/articles/article.aspx?p=1409801&seqNum=2 – Alexei Levenkov Jan 15 '15 at 20:01
1

One of the techiques here is to actually separate UI and long running stuff into separate processes, so they don't interfere.

It's quite possible that the garbage collector is pausing all the threads to do cleaning of heap, thus you experience a lag.

You could also try to use different GC modes, such as concurrent, background.. and see how they affect the performance.

It might be also possible to raise the priority of UI thread, and lower the priority of other worker threads, though it's a bit unclear why you have so many threads at all.

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

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • now these are some solid suggestion. can you elaborate more ? how to separate processes ? as you said GB can be also pretty much effecting this and one of the things i suspicioused. and how do i set different mode gb ? ty very much. also if separate process the communication between threads would be lost ? it looks like not possible. – Furkan Gözükara Jan 15 '15 at 17:55
  • i changed to Server Version and it seems like made huge impact :D – Furkan Gözükara Jan 15 '15 at 18:46
  • i suppose default GC is not server version for wpc application right ? – Furkan Gözükara Jan 15 '15 at 18:47