3

I have a little problem with Threads in this code..

I just want to run a lot of tasks together, and continue when all of them finish.

while (true)
{
    //   Run tasks together:
    foreach (object T in objectsList)
    {
        if (T.something>0)
            var task = Task.Factory.StartNew(() => T.RunObject());
            task.ContinueWith(delegate { ChangeObject(T, 1); }, TaskContinuationOptions.NotOnFaulted);
    }
    //   <-- Here I want to wait for all the task to be finish.
    //   I know its task.Wait() but how to waitAll()?
    System.Threading.Thread.Sleep(this.GetNextTime()); 
    var RefreshObjects = new Task(loadObjectsList); RefreshObjects .Start(); RefreshObjects.Wait();
}

I don't know how many objects will be in objectsList and I don't know if T.something will be > 0. so I can't just use:

Task[] Tasks = new Task[objectsList.count()]
for (int T=0; T<objectsList.count(); ++T)
{
    if (objectsList[T].something>0)
        var task = Task.Factory.StartNew(() => objectsList[T].RunObject());
        task.ContinueWith(delegate { ChangeObject(objectsList[T], 1); }, ...);
}
Task.WaitAll(Tasks);

Because Tasks will contains nulls when objectsList[T].something!>0...

Thanks for any advice!

2 Answers 2

3

Just switch the condition and create a List of tasks only for the objects which matches your criteria.

var tasks = objectsList
            .Where(x => x.Something() > 0)
            .Select(x => {
                            var task = Task.Factory.StartNew(() => x.RunObject());
                            task.ContinueWith(t => ChangeObject(....));
                            return task;
                         })
            .ToArray();

    Task.WaitAll(tasks);

Your code sample just waits for RunObject()to complete! If this is desired skip the rest of my answer. If you want to wait for the continuation to complete, too you can use this

var tasks = objectsList
            .Where(x => x.Something() > 0)
            .Select(x => Task.Factory.StartNew(() => x.RunObject()).ContinueWith(t => ChangeObject(....)))
            .ToArray();

    Task.WaitAll(tasks);

because ContinueWith generates a new Task.

Sign up to request clarification or add additional context in comments.

3 Comments

You can easily avoid making the select a statement delegate by calling ContinueWith on the task without assigning it to a varaible
Depends.. if he wants to wait for the continuation to complete, too he can. If he just wants for the initial task to complete he has to go with the statement.
Realy helpful! Thanks.
1

If objectsList implements IEnumerable, (as an array does), (And there are less than 64 objects in the list), you can use this:

public delegate void SyncDelegatesInParallelDelegate<in T>(T item);
public static class ParallelLinqExtensions
{
    public static void SyncDelegatesInParallel<T>(
        this IEnumerable<T> list, 
        SyncDelegatesInParallelDelegate<T> action)
    {
        var foundCriticalException = false;
        Exception exception = null;
        var waitHndls = new List<WaitHandle>();

        foreach (var item in list)
        {
            // Temp copy of session for modified closure
            var localItem = item;
            var txEvnt = new ManualResetEvent(false);

            // Temp copy of session for closure
            ThreadPool.QueueUserWorkItem(
                 depTx =>
                 {
                     try { if (!foundCriticalException) action(localItem); }
                     catch (Exception gX) 
                     { exception = gX; foundCriticalException = true; }
                     finally { txEvnt.Set(); }
                 }, null);
            waitHndls.Add(txEvnt);
        }
        if (waitHndls.Count > 0) WaitHandle.WaitAll(waitHndls.ToArray());
        if (exception != null) throw exception;
    }
}

you would call it like this

 objectsList.SyncDelegatesInParallel(delegate { ChangeObject(T, 1);});

1 Comment

This won't work if there are more than 64 objects in the objectsList because that is the limit on the number of wait handles.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.