I am doing probes with the new TAP pattern, using Task and CTP to implement async methods.
I have the following code:
private async void btnAsync01_Click(object sender, RoutedEventArgs e)
{
UpdateTxtLog("Enter in button Async01: " + System.DateTime.Now);
double result = await method01Async();
UpdateTxtLog("exit in button Async01: " + System.DateTime.Now);
UpdateTxtLog("result: " + result.ToString());
}
Is the button of the GUI that let me test async methods.
I can have the following implementations of the method01Aync.
First:
private async Task<double> method01Async()
{
return await Task.Factory.StartNew<double>(slowMethod);
}
private double slowMethod()
{
double doubleDummy = 0;
for (double i = 0; i < 1000000000; i++)
{
doubleDummy++;
}
return doubleDummy;
}
Second
private Task<double> method01Aync()
{
return Task.Factory.StartNew<double>(() =>
{
//O métodos auxiliares lentos... etc.
double doubleDummy = 0;
for (double i = 0; i < 1000000000; i++)
{
doubleDummy++;
}
return doubleDummy;
});
}
Third
private Task<double> method01Aync()
{
return TaskEx.Run<double>(() =>
{
double doubleDummy = 0;
for (double i = 0; i < 1000000000; i++)
{
doubleDummy++;
}
return doubleDummy;
});
}
Fourth
private Task method01Async()
{
return TaskEx.Run(slowMethod);
}
Fith
private Task<double> method01Async
{
return TaskEx.Run<double>(() =>
{
return metodoLento();
});
}
My results are that the implementation 1 and 4 take me 22s aprox. to finish meanwhile the other two takes 5s. Why does exist this difference? In the implementation 1 and 4, only use an auxiliary method with the same code with the loop.
I have notice that if I use the slowMethod() as parameter of the constructor of the Task is very slow and if I use delegates in the TaskEx or in task Factory is fast. Why does it happen this? Which is the difference?
Which is the difference of using Task.Factory or TaskEx.Run?
What is the best practice to use async with task with the TAP pattern?
Performance testing is a tricky subject.
Trying to ‘trick’ the compiler into thinking there’s work to be done when you’re just using a loop and counter is likely to cause inconsistent behaviour.
This is before mentioning the fact that there’s no warm up before the timing, this is likely done with Debug mode on, and the timing code itself isn’t shown.
All in all – assume that minor changes in the way you write how you call a long running process in the real world will not affect your performance materially.