11

This may be an odd question and it is really for my educational purpose so I can apply it in future scenarios that may come up.

I am using C#.

I am stress testing so this is not quite production code.

I upload data to my server via a web service.

I start the service off using a Task.Run.

I check to see if the Task is completed before allowing the next Run.Task to begin.

This is done within a loop.

However, because I am using a modular declared Task will not the result be affected? I could declare a local Task.Run variable but I want to see how far I can get with this question 1st.

If the Task.Run can raise an event to say it is completed then this may not be an issue?

This is my code:

//module declaration:

private static Task webTask = Task.Run(() => { System.Windows.Forms.Application.DoEvents(); });

//in a function called via a timer

if (webTask.IsCompleted)
{
   //keep count of completed tasks
}


webTask = Task.Run(() =>
{
    try 
    { 
         wcf.UploadMotionDynamicRaw(bytes);  //my web service
    }
    catch (Exception ex)
    {
        //deal with error
    }
);
Daniel
  • 1,695
  • 15
  • 33
Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179

2 Answers2

16

IMO you do not need the timer. Using Task Continuation you subscribe to the done event:

System.Threading.Tasks.Task
.Run(() => 
{
    // simulate processing
    for (var i = 0; i < 10; i++)
    {
        Console.WriteLine("do something {0}", i + 1);
    }
})
.ContinueWith(t => Console.WriteLine("done."));

The output is:

do something 1
do something 2
.
.
do something 9
do something 10
done

Your code could look like this:

var webTask = Task.Run(() =>
{
    try 
    { 
        wcf.UploadMotionDynamicRaw(bytes);  //my web service
    }
    catch (Exception ex)
    {
        //deal with error
    }
}).ContinueWith(t => taskCounter++);

With task continuation you could even differentiate between failed and success process result, if you want to count only successfull tasks - using the TaskContinuationOptrions.

keenthinker
  • 7,645
  • 2
  • 35
  • 45
  • 1
    Hi, I was using the timer just for stress testing and completely agree with you. The example on MSDN is different to yours and I prefer yours. Much clearer. Thank You – Andrew Simpson Jan 04 '15 at 10:31
3

You can wait for your task to complete by awaiting your task like this

await webTask;

that will asynchronously wait for 'webTask' to complete. Instead of the timer you can use await Task.Delay which will asynchronously wait for the delay to expire. I would also consider making the wcf call asynchronous so you don't have to call inside Task.Run. See this question for some tips.

I'd rewrite the code as follows:

public async Task UploadAsync()
{
    while(true)
    {
        await Task.Delay(1000); // this is essentially your timer

        // wait for the webTask to complete asynchrnously
        await webTask;

        //keep count of competed tasks

        webTask = Task.Run(() =>
                        {
                            try 
                            { 
                                // consider generating an asynchronous method for this if possible.
                                wcf.UploadMotionDynamicRaw(bytes);  //my web service
                            }
                            catch (Exception ex)
                            {
                                //deal with error
                            }
                        });     
    }
}
Community
  • 1
  • 1
NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61
  • Hi, thanks for the different answer. Much appreciated. I was aware of the await but i wanted to have async. The reason for all this is to monitor whether the web server is keeping up with my repetitive calls. By monitoring the queue I can (hopefully) detect this. – Andrew Simpson Jan 04 '15 at 11:06