0

An example :

try
{
    var myTask = Task.Run(async () =>
    {
        await Task.Delay(1);
    });

    myTask.ContinueWith(myContinuedTask =>
    {
        lock (myTask)
        {
            Task.Delay(1).Wait();
            Console.WriteLine(myContinuedTask.Id);
        }
    });
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

1) When myContinuedTask lock myTask, it's like making lock(this), right ?

2) This is not a good idea if the instance is used outside the control of this code, right ?

3) If this instance is only used inside the control of this code, is it possible that myContinuedTask will Never get the lock and, thus, will stay in a waiting state ? I know that tasks are managed by a TaskScheduler. And I don't know if this one is making some lock on the task instances which could possibly lead to a dead lock ?? (i need more info)

4) The Id field of a Task is not guarented to be unique. It's an int, so 4^32 max tasks can exists, right ? This seems really low. Is it per process, per thread, per session, ... ?

Thank you for your help :)

zizou
  • 49
  • 1
  • 6

1 Answers1

0

1) When myContinuedTask lock myTask, it's like making lock(this), right ?

No; it's the same as lock(myContinuedTask).

2) This is not a good idea if the instance is used outside the control of this code, right ?

Correct. You want to always lock on private or local scope variables whenever possible. In addition, I recommend having a separate object that is only used as a lock and nothing else.

3) If this instance is only used inside the control of this code, is it possible that myContinuedTask will Never get the lock and, thus, will stay in a waiting state ? I know that tasks are managed by a TaskScheduler. And I don't know if this one is making some lock on the task instances which could possibly lead to a dead lock ?? (i need more info)

Sure, it's possible. As soon as you expose an object instance that you use for locking, you encounter the possibility of deadlocks.

4) The Id field of a Task is not guarented to be unique. It's an int, so 4^32 max tasks can exists, right ? This seems really low. Is it per process, per thread, per session, ... ?

They just start duplicating, that's all. No worries.


Other problems with the code include:

  • Using ContinueWith instead of await.
  • Using Task.Delay(..).Wait() instead of Thread.Sleep.

Also, since this is asynchronous code, you may want to consider using SemaphoreSlim instead of lock.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • For the question 3, I don't think you have answered correctly to my question. It's about locking a task instance. And you answered with a general answer. The thing is, I don't know how task scheduler work internally and thus don't know if he could lock the task instance and thus lead to a dead lock. – zizou May 03 '16 at 19:55