3
\$\begingroup\$

Can I use task.Wait(); like that? Note that when I call task.Wait the task is probably already finished.

And probably you can suggest better pattern.

class A {
    private Task task1;
    private Task task2;

    ...
    public void Connect() {
        stayConnected = true;
        task1 = Task.Factory.StartNew(....,
            while (stayConnected) {
                ....
            }
            LongRunning);
        task2 = Task.Factory.StartNew(....,
            while (stayConnected) {
                ....
            }
            LongRunning);
    }

    private volatile bool stayConnected;

    // should be synchronous. when return everything should be disconected
    public void Disconnect() {
        stayConnected = false;
        task1.Wait();
        task1 = null;
        task2.Wait();
        task2 = null;
    }

}
\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

You can use a CancellationToken and Task.WaitAll(...) to do this...

public class A
{
    private readonly CancellationTokenSource tokenSource = new CancellationTokenSource();
    private Task task1;
    private Task task2;

    public void Connect()
    {
        task1 = Task.Factory.StartNew(SomeWork, tokenSource.Token);
        task2 = Task.Factory.StartNew(SomeWork, tokenSource.Token);
    }

    public void Disconnect()
    {
        tokenSource.Cancel();
        Task.WaitAll(task1,task2);
    }

    public void SomeWork(object o)
    {
        CancellationToken token = (CancellationToken)o;
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine("working...");
        }
    }
}

For more information on managed threads check this and this article on MSDN. Enjoy :D

\$\endgroup\$
6
  • \$\begingroup\$ why cancellationtoken is better than just "volatile boolean"? in general i prefer "easy to port to c++" code. \$\endgroup\$ Nov 29, 2012 at 15:54
  • \$\begingroup\$ I think CancellationToken should be used when you want to cancel a Task prematurely. I think that's not the case here. Also, canceling the Task properly (which you didn't do) would mean WaitAll() would throw an exception. \$\endgroup\$
    – svick
    Nov 29, 2012 at 16:39
  • \$\begingroup\$ You can certainly use volatile if you want to keep it simple. \$\endgroup\$
    – tweakch
    Nov 29, 2012 at 16:48
  • \$\begingroup\$ @svick why does it throw an exception? \$\endgroup\$
    – tweakch
    Nov 29, 2012 at 17:01
  • \$\begingroup\$ @Alechandro Because the Tasks would be canceled. Wait() and WaitAll() throw an exception when you wait on a canceled Task. \$\endgroup\$
    – svick
    Nov 29, 2012 at 17:51
0
\$\begingroup\$

Task.Wait() should just return true if the task is completed, so sure you can. However, you should better use waiting with timeout or TimeSpan parameter if you have actions inside of while { } loop that can possibly cause a freeze.

\$\endgroup\$
1
  • \$\begingroup\$ Task.Wait() without a timeout doesn't return anything. \$\endgroup\$
    – svick
    Nov 29, 2012 at 18:41
0
\$\begingroup\$

This seems like a reasonable approach to me. You could improve it a bit by using Task.WaitAll() but that won't change much.

Also, I wouldn't set the fields to null unless I had good reason to do it. Yeah, those Tasks are not useful for anything anymore, but they are also almost free.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.