5

I am using System.ComponentModel.BackgroundWorker in my WPF application.

How can I set timeout for BackgroundWorker ?

NoWar
  • 36,338
  • 80
  • 323
  • 498
Armen Khachatryan
  • 831
  • 3
  • 22
  • 37

2 Answers2

4

My suggestion is following

backgroundworker1 does the work - it accepts cancellation so you can make it stop.

backgroundworker2 does a loop while the time out is pending, and on time out completes.

If backgroundworker1 is still running, the RunWorkerComplete of this BackgroundWorker, kills off backgroundworker1..

This should also accept cancellation so that if backgroundworker1 completes and this is still running, you can cancel it.

NoWar
  • 36,338
  • 80
  • 323
  • 498
BugFinder
  • 17,474
  • 4
  • 36
  • 51
  • Probably but, to get a fairly accurate time out, as well as the functionality, there arent many options. You could do some form of descendant and constantly check for time passed in your original worker, but, if you had any form of blocking call it could well exceed the timeout. – BugFinder Jul 03 '12 at 15:02
4

BackgroundWorker does not directly support a timeout, but it does support cancellation. This will work well if the work being done is an a loop or other structure where you can periodically check the CancellationPending member to then abort. You will need some thing else to tell the background worker to cancel after the timeout. Here I used an async call of an action.

    static void Main( string[] args )
    {
        var bg = new BackgroundWorker { WorkerSupportsCancellation = true };
        bg.DoWork += LongRunningTask;

        const int Timeout = 500;
        Action a = () =>
            {
                Thread.Sleep( Timeout );
                bg.CancelAsync();
            };
        a.BeginInvoke( delegate { }, null );

        bg.RunWorkerAsync();

        Console.ReadKey();
    }

    private static void LongRunningTask( object sender, DoWorkEventArgs eventArgs )
    {
        var worker = (BackgroundWorker)sender;
        foreach ( var i in Enumerable.Range( 0, 5000 ) )
        {
            if ( worker.CancellationPending )
            {
                return;
            }
            else
            {
                //Keep working
            }
        }
    }

If this doesn't really fit what your are trying to accomplish you may be interested in the generic timeout solutions found at Implementing a timeout on a function returning a value or Implement C# Generic Timeout. You could use those inside the BackgroundWorker.

Community
  • 1
  • 1
vossad01
  • 11,552
  • 8
  • 56
  • 109
  • Thank you but it not works , eventArgs.Cancel never comes true . – Armen Khachatryan Jul 04 '12 at 09:58
  • @ArmenKhachatryan Oh, of course it does not, I was checking the wrong object for cancel information (^_^;). I have edited with a fix. – vossad01 Jul 04 '12 at 13:51
  • Works Like a Charm. Many Thanks.... If you're going OO mode ;-) , Your can Global var bg = new BackgroundWorker and use CancelAsync(); anywhere in your code. – Roy Doron Sep 12 '16 at 12:45