fbpx
Welcome, Guest
Username: Password: Remember me
Share your code snippets, screen shots etc. here
  • Page:
  • 1

TOPIC: The BackgroundWorker or "How to make responsive WPF windows"

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #1

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
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):
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:
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
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it
Attachments:

Please Log in or Create an account to join the conversation.

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #2

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#)...
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

Please Log in or Create an account to join the conversation.

Last edit: by NickFriend.

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #3

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
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.
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it
Attachments:

Please Log in or Create an account to join the conversation.

Last edit: by wriedmann.

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #4

Hi Wolfgang,

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

Nick

Please Log in or Create an account to join the conversation.

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #5

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
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
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

The BackgroundWorker or "How to make responsive WPF windows" 2 years 3 months ago #6

  • Phil Hepburn
  • Phil Hepburn's Avatar
  • Offline
  • Posts: 737
  • Karma: 7
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))

Please Log in or Create an account to join the conversation.

  • Page:
  • 1