Возможно ли иметь общий метод для фоновых работников? - PullRequest
3 голосов
/ 21 декабря 2011

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

Сейчас я нахожусь в точке, где он временно отключает интерфейс на пару секунд, но я бы хотелсоздать background workers для выполнения этих задач.

Проблема с их созданием состоит в том, что существует около 9 кнопок, которым потребуется фоновый работник, и все, что они делают, это вызывают другой метод в DLL.Есть ли способ использовать общий метод для создания этих фоновых рабочих, используя API для фоновых рабочих, или я должен создать Enum, который соответствует каждой кнопке и является параметром, принимаемым методом, который создает фоновый рабочий.Значит, я мог бы использовать простой switch для выполнения любого метода из библиотеки DLL, которую я выбрал?

Пример кода:

    void bg_DoWorkImports(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        try
        {
            e.Result = EngineBllUtility.GetNotImportedFiles(connectionString);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    void bg_RunWorkerCompletedImports(object sender, RunWorkerCompletedEventArgs e)
    {
        DataSet temp = (DataSet)e.Result;
        if (e.Result != null)
        {
            importFileGridView.DataSource = temp.Tables[0];
        }
    }

Ответы [ 4 ]

2 голосов
/ 21 декабря 2011

Вместо использования BackgroundWorker, альтернативой будет использование TPL.Это позволит вам написать код непосредственно в каждом члене:

void buttonImport_Click(object sender, DoWorkEventArgs e)
{
    Task.Factory
      .StartNew( () => return EngineBllUtility.GetNotImportedFiles(connectionString))
      .ContinueWith( t =>
    {        
        try
        {
            if (t.Result != null)
            {
                 importFileGridView.DataSource = t.Result.Tables[0];
            }
        }
        catch (AggregateException ex)
        {
            MessageBox.Show(ex.InnerException.Message);
        }
    }, TaskScheduler.FromCurrentSynchronizationContext());
}
2 голосов
/ 21 декабря 2011

Вы можете передать Func<T> методу, который создает BackgroundWorker, и вызвать это действие изнутри к DoWork-событию.

Как то так

public class BackgroundWrapper<T>
{
    private Func<T> workMethod;
    private Action<T> completeMethod;
    public static void StartBackgroundworker(Func<T> workMethod, Action<T> completeMethod)
    {
        BackgroundWrapper<T> bWrap = new BackgroundWrapper<T>();
        bWrap.workMethod = workMethod;
        bWrap.completeMethod = completeMethod;
        bWrap.Start();
    }

    private void Start()
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.RunWorkerAsync();
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        completeMethod((T)e.Result);
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        e.Result = workMethod();
    }
}
1 голос
/ 21 декабря 2011

Конечно, я не понимаю, почему вы не могли создать для этого функцию типа «распределительный щит».На самом деле, вы можете захотеть сделать это, потому что это сделало бы вещи немного более модульными и способствовало бы повторному использованию кода.

Что касается перечислений, лично я создаю классы для передачи большого количества аргументов в и изтакие вещи.

0 голосов
/ 21 декабря 2011

Я думаю, вам нужно создать какой-нибудь механизм организации очередей, в котором один фоновый работник выбирает каждое из заданий, связанных с нажатием кнопки, и запускает одно за другим.

...