xsharp.eu • The BackgroundWorker or "How to make responsive WPF windows"
Page 1 of 1

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Sun Dec 11, 2016 10:54 am
by wriedmann
Unfortunately, in WPF the AppExec() call does not work if you start a longer process from your window.
The first approach would be to use ASYNC/AWAIT, but unfortunately this works only if you are using some methods that are implementing this.

For own processings, the BackgroundWorker class (from System.ComponentModel) seems to be a better solution.

Please look at this code (how to start such a processing):

Code: Select all

method StartButtonClick( oSender as object, e as RoutedEventArgs ) as void   
	
if _oWorker == null
  _oWorker := BackgroundWorker{}
  _oWorker:WorkerReportsProgress := true
  _oWorker:WorkerSupportsCancellation := true
  _oWorker:DoWork += ExecuteProcessAsync
  _oWorker:ProgressChanged += ProgressProcessAsync
  _oWorker:RunWorkerCompleted += CompletedProcessAsync
  _oWorker:RunWorkerAsync() 
endif
	
return

method ExecuteProcessAsync( oSender as object, e as DoWorkEventArgs ) as void
  local oProcess as AsyncProcess
	
  oProcess := AsyncProcess{ _oWorker }
  oProcess:Process()
	
return
and the relative AsyncProcess implementation:

Code: Select all

class AsyncProcess
  protect _oWorker as BackgroundWorker
	
constructor( oWorker as BackgroundWorker )
	
  _oWorker := oWorker
	
  return	
	
method Process() as void 
  local nLoop as int
  local nInner as int
  local nMax as int
  local cString as string
  local cMessage as string
	
  nMax := 32000
  for nLoop := 1 upto nMax
    for nInner := 1 upto nMax
      cString := string{ 'X', nMax }
    next              
    cMessage := String.Format( "round {0} of {1}", nLoop:ToString(), nMax:ToString() ) 
    _oWorker:ReportProgress( ( nLoop * 100 / nMax ), cMessage )
    Thread.Sleep( 100 )      
    if _oWorker:CancellationPending
       exit
    endif
   next   
   _oWorker:ReportProgress( ( nLoop * 100 / nMax ), "terminated" )
	
end class
You can find the complete working program as attachment to this message - it is a zipped XIDE export file.

Wolfgang

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Mon Dec 12, 2016 9:56 am
by NickFriend
Hi Wolfgang,

Task/await, etc. is well worth getting into, as it simplifies the coding of asynchronous code dramatically.

As a starting point you can run more or less any method asynchronously like this (sorry about the C#)...

Code: Select all

private async void MethodA()
{
    await Task.Factory.StartNew(()=> { this.MethodB(); }); 
    // MethodB called asynchronously, control returns immediately to whatever called MethodA
    ... code here gets executed when MethodB completes...
}
Creating your own asynchronous methods is actually quite straightforward as well, once you work out how to do it (as ever that's the difficult bit). But it does make async code much more readable and manageable.

Nick

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Mon Dec 12, 2016 10:06 am
by wriedmann
Hi Nick,

before discovering the BackgroundWorker class I had tried (successfully) ASYNC/AWAIT, but I feel the BackgroundWorker is a bit clearer to use, and it needs less and clearer code for implementing progress information and the possibility to abort the background process.

Therefore I think the BackgroundWorker is better suited for my needs.

Wolfgang

P.S. I have to admit that it took some time to understand ASYNC/AWAIT. I have added my async/await sample here as attachment.

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Mon Dec 12, 2016 10:16 am
by NickFriend
Hi Wolfgang,

I like your Task/await version better! But of course everyone has their own preferred style.

Nick

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Mon Dec 12, 2016 10:21 am
by wriedmann
Hi Nick,

did you know that one: ask 5 programmers for a solution of a programming problem, and you'll receive at least 10 different solutions.

Styles and preferences are different - and I'm pretty sure my preferences are a bit unusual for the .NET world, as I prefer code to XAML.

Wolfgang

The BackgroundWorker or "How to make responsive WPF windows"

Posted: Mon Dec 12, 2016 5:09 pm
by Phil Hepburn
Be CAREFUL Wolfgang - its party season, and you may not get many invitations ;-0)

Have a season drink on me - Ho ! Ho! Ho!

Guess who ?

:-0))