I am using task factory to spawn parallel threads and my code is as below. I have the requirement to print the completion time of every thread but dont know how to check for every thread. Currently my code is waiting for all tasks to finish and then calculating the time.
stp1.Start();
for (int i = 0; i < tsk.Length; i++)
{
tsk[i] = Task.Factory.StartNew((object obj) =>
{
resp = http.SynchronousRequest(web, 443, true, req);
}, i);
}
try
{
Task.WaitAll(tsk);
}
stp1.Stop();
a measure of the time it takes a user to perform a task (from start to finish). This is a typical metric in usability evaluation.
Task. Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!
StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.
Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The following example calls the parameterless Wait() method to wait unconditionally until a task completes. The task simulates work by calling the Thread.
You can add a continuation to the Task
. Continuation is a method which will be called when the given Task
is completed.
for (int i = 0; i < tsk.Length; i++)
{
tsk[i] = Task.Factory.StartNew((object obj) =>
{
resp = http.SynchronousRequest(web, 443, true, req);
}, i);
tsk[i].ContinueWith(antecedent=>
{
//antecedent is completed
//Do whatever here
});
}
If you need to time individual tasks, you need one stopwatch per Task. You can start the StopWatch
inside StartNew
and stop it in ContinueWith
.
If this is your actual code, you can simply time the synchronous operation which you invoke (http.SynchronousRequest in this case). For example following code is enough.
for (int i = 0; i < tsk.Length; i++)
{
tsk[i] = Task.Factory.StartNew((object obj) =>
{
StopWatch watch = StopWatch.StartNew();
resp = http.SynchronousRequest(web, 443, true, req);
watch.Stop();
Console.WriteLine(watch.Elapsed);
}, i);
}
Btw, Network operations are inherently asynchronous; There will be asynchronous API available, you can use it instead of wrapping a synchronous web request in Task. For instance, maybe HttpClient.SendAsync
.
I'd start off by saying that you don't need threadpool threads to execute async IO bound operations. Instead of using Task.Factory.StartNew
, use naturally asynchronous API's such as the one HttpClient
offers, for example.
Then, i'd say you can use Task.WhenAny
to wait on the completion of each of your tasks as they finish:
// Note I'm assuming some kind of async implementation which returns a Task<T>
var tasks = tsk.Select(req => http.AsyncRequest(web, 443, true, req));
while (tasks.Count > 0)
{
var finishedTask = await Task.WhenAny(tasks);
// Do something with finishedTask
tasks.Remove(finishedTask);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With