The problem is that dispatcher blocks the MainWindow thread until it is executed all of the queued AddOutputLine()s. Can these calls be non-blocking for a wpf control?
//TaskPage.xaml.cs [MTAThread] public void AddOutputLine(string line = "") { try { Session.TaskPage.Dispatcher.BeginInvoke(new Action(delegate { txtOutput.Text += "[" + DateTime.Now + "] " + line + Environment.NewLine; txtOutput.ScrollToEnd(); })); } catch (Exception ex) { Program.SetCurrentStatus("Error occured : "+ex.Message); } } In this class that invokes the Action parameter:
//BackgroundUploader.cs private Action<string> _log; public BackgroundUploader(Client client, Action<string> log = null) { _log = log; _client = client; } while doing this:
//BackgroundUploader.cs public void RunThreadProc() { try { _log?.Invoke("Timeout interval set for BackGround Task."); while (!Stop) { //the problematic blocking of WPF Control starts here var inOutFiles = CreateXML(_sqlStrings, _outputNames, _outputDirectory); Send(inOutFiles, _outputDirectory); LastRunTime = DateTime.Now; _log?.Invoke($"Waiting for {_waitMinutes} minutes..."); //the Control returns to processing messages System.Threading.Thread.Sleep((int)TimeSpan.FromMinutes(_waitMinutes).TotalMilliseconds); } _log?.Invoke("BackGroundTask canceled."); } catch (Exception ex) { _log?.Invoke($"Error while executing background task: {ex.Message}"); } } The RunThreadProc() is called from Control like this:
//TaskPage.xaml.cs _backgroundThread = new System.Threading.Thread(bU.RunThreadProc); _backGroundThread.Start(); I also cannot use Bcl.Async because it's failing on Task result with method that uses async modifier on Windows Server 2003 target OS.
edit: I encountered the problem inside of the background class, its methods run synchronously, even though they are in a different thread.
Microsoft.Bcl.Asyncpackage was created to allow usingasync/awaitfor precisely such systems (Windows XP, Windows 2003). What was the actual problem when you tried using it?TextBox.Textproperty over and over is simply bad and hugely inefficient coding. No amount of threading can fix this. Use data binding instead to bind the control to a property, and only raise the NotifyChanged event when you really want to update the screen. Even better, use aList<T>property and bind a ListView to it. Instead of creating new strings over end over, you'll only need to append items to that List<T>. WPF will only render the visible items too