How to wait correctly until BackgroundWorker completes?

前端 未结 10 1212
既然无缘
既然无缘 2020-12-02 11:19

Observe the following piece of code:

var handler = GetTheRightHandler();
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += OnAsyncOperationCompleted;         


        
10条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-02 12:03

    I used Tasks with a BackgroundWorker

    You can create any number of tasks and add them to a list of tasks. The worker will start when a task is added, restart if a task is added while the worker IsBusy, and stop once there are no more tasks.

    This will allow you to update the GUI asynchronously as much as you need to without freezing it.

    This works as is for me.

        // 'tasks' is simply List that includes events for adding objects
        private ObservableCollection tasks = new ObservableCollection();
        // this will asynchronously iterate through the list of tasks 
        private BackgroundWorker task_worker = new BackgroundWorker();
    
        public Form1()
        {
            InitializeComponent();
            // set up the event handlers
            tasks.CollectionChanged += tasks_CollectionChanged;
            task_worker.DoWork += task_worker_DoWork;
            task_worker.RunWorkerCompleted += task_worker_RunWorkerCompleted;
            task_worker.WorkerSupportsCancellation = true;
    
        }
    
        // ----------- worker events
        void task_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (tasks.Count != 0)
            {
                task_worker.RunWorkerAsync();
            }
        }
    
        void task_worker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
    
                foreach (Task t in tasks)
                {
                    t.RunSynchronously();
                    tasks.Remove(t);
                }
            }
            catch
            {
                task_worker.CancelAsync();
            }
        }
    
    
        // ------------- task event
        // runs when a task is added to the list
        void tasks_CollectionChanged(object sender,
            System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (!task_worker.IsBusy)
            {
                task_worker.RunWorkerAsync();
            }
        }
    

    Now all you need is to create a new Task and add it to the List<>. It will be run by the worker in the order it was placed into the List<>

    Task t = new Task(() => {
    
            // do something here
        });
    
        tasks.Add(t);
    

提交回复
热议问题