Как заставить последовательное выполнение на BackgroundWorker - PullRequest
0 голосов
/ 29 февраля 2012

У меня есть событие backgroundworker_dowork() в C # .Net 4, которое вызывает три метода, и я хочу, чтобы они выполнялись синхронно.

Учитывая мои ограничения, метод 3 должен выполняться после метода 2, а метод 2 должен выполняться после метода 1.

Однако в BackgroundWorker все три метода выполняются асинхронно.

Как я могу это изменить?

private void bgwLoading_DoWork(object sender, DoWorkEventArgs e)
{
    ArrayList a = (ArrayList)e.Argument;

    string[] fileNames = (string[])a[0];
    bool isLoad = (bool)a[1];

    this.loadMultiImages(fileNames, isLoad);
}

private void loadMultiImages(string[] fileNames, bool isLoad)
{
    // I want to execute the following codes sequentially.
    Bitmap newBtmap = saveJpeg();
    this.SafeInvoke(d => d.imageList.Images.Add(newBtmap));
}

Поскольку SafeInvoke() занимает меньше времени, чем saveJpeg(), он начинает выполняться до выполнения saveJpeg(), изменяя ход выполнения, который я хочу.

Ответы [ 2 ]

2 голосов
/ 29 февраля 2012

Если метод 3 зависит от метода 2, а метод 2 зависит от метода 1, , то есть только один способ выполнить их : последовательно . Даже если вы выполняете несколько потоков, выполняя их, вам все равно придется выполнять методы в порядке 1-> 2-> 3.

Вы можете использовать различные конструкции, чтобы заставить метод 2 ждать, пока метод 1 и метод 3 ждут, когда метод 2, но вы по-прежнему принципиально выполняете методы синхронно, так что вы можете просто использовать 1 поток для выполнения всех 3 методов .

0 голосов
/ 29 февраля 2012

Вы можете захотеть что-то подобное. Используйте событие RunWorkerCompleted для вызова метода после завершения фоновой операции:

var bg1 = new System.ComponentModel.BackgroundWorker();
var bg2 = new System.ComponentModel.BackgroundWorker();
var bg3 = new System.ComponentModel.BackgroundWorker();
bg1.RunWorkerCompleted += (s, e) =>
{
    bg2.RunWorkerAsync();
};
bg2.RunWorkerCompleted += (s, e) =>
{
    bg3.RunWorkerAsync();
};
bg1.RunWorkerAsync();

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

Если вы хотите запустить 3 процедуры синхронно в фоновом режиме, просто вызовите их синхронно в фоновом потоке:

var bg1 = new System.ComponentModel.BackgroundWorker();
bg1.DoWork += (s, e) =>
{
    Process1();
    Process2();
    Process3();
};
bg1.RunWorkerAsync();
...