VAAA
VAAA

Reputation: 15039

c# add delay between concurrent task executions

I have the following tasks that sends some data to a TCP Socket:

var tasks = new List<Task>();

foreach(int patient in patients)
{
    //tasks.Add(Work(patient));
    tasks.Add(Task.Factory.StartNew(() =>
    {
        var message = BuildCommand();
        var bytes = Socket.StartClient(message);

        var bits = new BitArray(bytes);
        var stringBytes = ToBitString(bits);

        SetResultsText(stringBytes + Environment.NewLine);

    }, TaskCreationOptions.LongRunning));
}

await Task.WhenAll(tasks.ToArray());

What I want is to add a delay between each task of about 200ms so they don't run exactly at the same time because I have seen that some packages are lost on the socket, so I want to delay a little bit each call to avoid this issue.

I have tried Task.Delay and Thread.Sleep and seems tasks still executing at same time.

Upvotes: 0

Views: 228

Answers (3)

Paulo Morgado
Paulo Morgado

Reputation: 14836

IF what you want is to run them sequentially and with a delay, just do that:

var first = true;
foreach(int patient in patients)
{
    if (!first)
    {
        await Task.Delay(200);
    }

    await Task.Run(() =>
    {
        var message = BuildCommand();
        var bytes = Socket.StartClient(message);
        var bits = new BitArray(bytes);
        var stringBytes = ToBitString(bits);

        SetResultsText(stringBytes + Environment.NewLine);
    });
 }

I think that's what you're asking, but I doubt very much that that's what you're needing. This is just a waste of threads.

Upvotes: 1

Joachim Isaksson
Joachim Isaksson

Reputation: 180867

If you don't want to run the tasks simultaneously anyway and assuming there's a reason not to just run the code synchronously removing the task entirely, it may be simpler to do everything in a single task sequentially instead;

var task = Task.Factory.StartNew(() =>
{
    foreach(int patient in patients)
    {
        var message = BuildCommand();
        var bytes = Socket.StartClient(message);

        var bits = new BitArray(bytes);
        var stringBytes = ToBitString(bits);
        SetResultsText(stringBytes + Environment.NewLine);
    }
}, TaskCreationOptions.LongRunning);

await task;

Upvotes: 3

Arphile
Arphile

Reputation: 861

object LockObject { get; set; }

public void Init() {
    LockObject = new object();
}

...YourMethod() {
    lock ( LockObject ) {
        ...YourTask
    }
}

Call YourMethod() will do it step by step.

LockObject will locked until YourTask finished, after then, it'll call another methodcall which you called.

you don't need to add 200ms each of tasks.

Upvotes: -2

Related Questions