All, I have a generic method called TaskSpin
, in this method I launch a Task
with an ascociated continutation
public TaskSpin(Func asyncMethod, object[] methodParameters)
{
...
asyncTask = Task.Factory.StartNew<bool>(() =>
asyncMethod(uiScheduler, methodParameters));
asyncTask.ContinueWith(task =>
{
// Finish the processing update UI etc.
}
...
}
The problem is now that I want to run multiple methods using TaskSpin
, but I need to restrict the methods to run one-at-a-time. So foreach row in some DataGridView
I want to do something like
foreach (DataGridViewRow row in this.DataGridViewUrg.Rows)
TaskSpin(Run(DrgDataRowInfo(row.Index)));
However, in the above the TaskSpin
method will exit immediately causing TaskSpin
to spin off the next method on yet another thread. This is no good as the Run
method write to a common set of files. What is the best way to queue these jobs?
Thanks for your time.
You could implement your own task queue and just keep processing the queue after each task is complete until it's empty e.g.
You should probably think about implementing synchronization by locking an object that Run requires before continuing. You would something like the following:
Although, I am pretty sure this will NOT guarantee that the tasks complete in order. This sounds like it might be important to you, so possibly my suggestion is not exactly what you want.
You can implement a "queue" of tasks using a continuation chain. This is easy to read and understand and will work as expected. Also, the "queueing" logic is now contained within your TaskSpin.
This will ensure that each new Task will only run once the last Task has been completed.
Edit: If you want your UI task to be included in the sequential queue, a simple change:
If your goal is to serialize updates to the UI, this has to happen anyway because UI can only be updated from the GUI thread. Fortunately, mechanisms to do this are already built in.
I note that you're using winforms. Given that, I suggest using a mechanism such as SafeInvoke. This will queue up code for execution on the GUI thread.