In Asp.net 4.0, mvc 4, i am using Task.
My reference Code::
List<Task> lstTask = new List<Task>();
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method1()));
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method2()));
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method3()));
try
{
Task.WaitAll(lstTask.ToArray(), 2000);
}
catch(AggregateException)
{
//just catch not to do anything
}
catch(Exception)
{
//just catch not to do anything
}
Now Method1, Method2, Method3 wil do web request. After Wait All , I will Loop through all the task and will get resutl from each task. Below is my reference code
foreach (var tsk in lstTask)
{
if (tsk.IsCompleted)
{
// Some other stuff
}
}
Method1/2/3 has below code:
public CustomClass Method1/2/3()
{
try
{
// Do Web request
// Do other process
return CustomClass;
}
catch(exception ex)
{
throw;
}
}
Now i was getting below error, "A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread."
it seems cause of this error is, main thread waits for 2 seconds. After its wait timeout, and main thread continues its execution.
But if Tasks (Method1/2/3) not yet completed, and continue their processing. If any Exception occurred in any task then it will directly throws that exception.
Now because main thread is not waiting (timeout) and could not catch that exception, so nobody catch this exception might cause this issue.
So as a solution , I used CancelToken. After wait timeout cancel the token. And in all tasks (Method1/2/3), before throw exception, will check if token has been canceled then not throw exception, otherwise throw it.
var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token;
List<Task> lstTask = new List<Task>();
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method1(token)));
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method2(token)));
lstTask.Add(Task<CustomClass>.Factory.StartNew(() => Method3(token)));
try
{
Task.WaitAll(lstTask.ToArray(), 2000, token);
tokenSource.Cancel();
}
catch(AggregateException)
{
//just catch not to do anything
}
catch(Exception)
{
//just catch not to do anything
}
public CustomClass Method1/2/3()
{
try
{
// Do Web request
// Do process
return CustomClass;
}
catch(exception ex)
{
if (!token.IsCancellationRequested)
{
throw;
}
}
return new CustomClass();
}
So is this proper solution?
No comments:
Post a Comment