learner
learner

Reputation: 81

How to force sequential execution on BackgroundWorker

I have a backgroundworker_dowork() event in C# .Net 4, that calls three methods, and I want them to execute synchronously.

Given my constraints, method 3 must execute after method 2, and method 2 must execute after method 1.

However, in the BackgroundWorker all three methods are executed asynchronously.

How can I change this?

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));
}

Since SafeInvoke() takes less time than saveJpeg(), it starts executing before the saveJpeg() is done, changing the flow of the execution I want.

Upvotes: 0

Views: 812

Answers (2)

Kiril
Kiril

Reputation: 40345

If method 3 depends on method 2 and method 2 depends on method 1, then there is only one way to execute them: sequentially. Even if you task multiple threads with executing them, you'll still have to execute the methods in order 1->2->3.

You can use various constructs to force method 2 to wait for method 1 and method 3 to wait for method 2, but you're still fundamentally executing the methods synchronously so you might as well just use 1 thread to execute all 3 methods.

Upvotes: 2

qxn
qxn

Reputation: 17574

You may want something like this. Use the RunWorkerCompleted event to call a method after the background operation completes:

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();

But, I'm not sure on the effectiveness of this pattern. If you want functions called synchronously, then call them synchronously. There's probably a better way to do that than using background workers.

If you want to run 3 procedures synchronously in the background, just call them synchronously in the background thread:

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

Upvotes: 0

Related Questions