Абстракция шаблона, замеченного с помощью BackgroundWorker - PullRequest
1 голос
/ 03 сентября 2011

Я замечаю пример, подобный приведенному ниже, в нескольких моих уроках. Как я могу абстрагироваться от этого? Есть предложения?

private void InitializeClass()
{
    BackgroundWorker bgw1 = new BackgroundWorker();
    bgw1.DoWork += (s,e) =>
    {
        // doing work
    };

    BackgroundWorker bgw2 = new BackgroundWorker();
    bgw2.DoWork += (s,e) =>
    {
        // doing work
    };

    BackgroundWorker bgw3 = new BackgroundWorker();
    bgw3.DoWork += (s,e) =>
    {
        // doing work
    };

    bgw1.RunWorkerAsync();
    bgw2.RunWorkerAsync();
    bgw3.RunWorkerAsync();
}

Ответы [ 2 ]

6 голосов
/ 03 сентября 2011
public static class Worker
{
    public static void Execute(params DoWorkEventHandler[] handlers)
    {
        foreach (DoWorkEventHandler handler in handlers)
        {
            BackgroundWorker worker = new BackgroundWorker();
            DoWorkEventHandler capturedHandler = handler;

            worker.DoWork += (sender, e) =>
            {
                try
                {
                    capturedHandler(sender, e);
                }
                finally
                {
                    worker.Dispose();    
                }
            };

            worker.RunWorkerAsync();
        }
    }
}

и затем:

Worker.Execute((s, e) =>
{
    // doing work
});

или если вы хотите запланировать несколько событий:

Worker.Execute(
    (s, e) => 
    {
        // doing work
    },
    (s, e) => 
    {
        // doing work
    },
    (s, e) => 
    {
        // doing work
    }
);

UPDATE:

Вот альтернатива, которая позволяет вам указать завершенный обработчик:

public class Worker
{
    public Worker Work(DoWorkEventHandler doWork, RunWorkerCompletedEventHandler complete)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += doWork;
        worker.RunWorkerCompleted += complete; 
        worker.RunWorkerAsync();
        return this;
    }
}

, а затем:

new Worker()
    .Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ })
    .Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ })
    .Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ });
1 голос
/ 03 сентября 2011

Может быть, вы можете сделать что-то вроде этого. A псевдокод :

public abstract class BaseClass 
{
     public abstract DoWork1();
     public abstract DoWork2();
     public abstract DoWork3();


     protected void InitializeClass()
     {
        BackgroundWorker bgw1 = new BackgroundWorker();
        bgw1.DoWork += (s,e) =>
        {
           DoWork1();
        };

        BackgroundWorker bgw2 = new BackgroundWorker();
        bgw2.DoWork += (s,e) =>
        {
           DoWork2();
        };

        BackgroundWorker bgw3 = new BackgroundWorker();
        bgw3.DoWork += (s,e) =>
        {
           DoWork3();
        };

        bgw1.RunWorkerAsync();
        bgw2.RunWorkerAsync();
        bgw3.RunWorkerAsync();
    }


}

после этого в любом производном классе, примерно так:

public class DerivedClass: BaseClass 
{
    public override DoWork1(){}  //DoWork1 concrete implementaiton

    public override DoWork2(){}  //DoWork2 concrete implementaiton

    public override DoWork3(){}  //DoWork3 concrete implementaiton

}

Поэтому, когда вы вызываете метод InitializeClass(), вы вызываете метод базового класса, который вызывает переопределения конкретного класса.

Примечание: Если число фоновых работников может варьироваться, вы можете объединить решение Дарина с этим (другими словами, иметь коллекцию вызывающих).

Надеюсь, это поможет.

...