Reputation: 13397
In a console application I use async-await as follows:
static void Main(string[] args)
{
// Task<Model>
var taskGetModel = Testcases.GetModel(22);
taskGetModel.Wait();
// Task without TResult
var taskSaveModel = Testcases.SaveModel(taskGetModel.Result);
taskSaveModel.Wait();
}
public async static Task<Model> GetModel(int number)
{
var baseData = await serviceagent.GetBaseData();
var model = await serviceagent.GetModel(baseData, number);
model.BaseData = baseData;
return model;
}
public static async Task SaveModel(Model model)
{
await serviceagent.SaveModel(model);
}
// as for the service methods:
public async Task SaveModel(Model model)
{
// the method `.ToCommunication` has the signature:
// public async Task<CommunicationModel> ToCommunication
var commodel = await new Mapper().ToCommunication(model);
// Proxy is the interface to the servce (ChannelFactory etc.)
// the method `.Save` has the signature:
// public async Task Save(CommunicationModel model)
await Proxy.Save(commodel);
}
public async Task<Model> GetModel(BaseData baseData, int number)
{
// NOT a task: CommunicationModel GetCommunicationModel
var commodel = Proxy.GetCommunicationModel(baseData, number);
// signature with Task: public async Task<Model> ToModel
return await new Mapper().ToModel(baseData, commodel);
}
In static main, the Task<TResult>
gives the nice result that the function GetModel
returns immediately with the Task
and I can wait for its result to finish.
Why does the Task in SaveModel
not return immediately?
The await
in SaveModel
is already awaited in that method.
Is it because it doesn not have a TResult
?
Upvotes: 3
Views: 1127
Reputation: 56536
Works for me. The following code...
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Task<Model>
var sw = Stopwatch.StartNew();
Console.WriteLine("1: " + sw.Elapsed);
var taskGetModel = GetModel(22);
Console.WriteLine("2: " + sw.Elapsed);
taskGetModel.Wait();
Console.WriteLine("3: " + sw.Elapsed);
// Task without TResult
var taskSaveModel = SaveModel(taskGetModel.Result);
Console.WriteLine("4: " + sw.Elapsed);
taskSaveModel.Wait();
Console.WriteLine("5: " + sw.Elapsed);
}
public async static Task<Model> GetModel(int number)
{
var baseData = await service.GetBaseData();
var model = await service.GetModel(baseData, number);
model.BaseData = baseData;
return model;
}
public static async Task SaveModel(Model model)
{
await service.SaveModel(model);
}
static Service service = new Service();
class Service
{
public Task SaveModel(Model model)
{
return Task.Delay(1000);
}
public async Task<Model> GetModel(object baseData, int number)
{
await Task.Delay(1000);
return new Model();
}
public async Task<object> GetBaseData()
{
await Task.Delay(1000);
return new object();
}
}
}
public class Model
{
public object BaseData { get; set; }
}
}
Outputs something like
1: 00:00:00.0000102
2: 00:00:00.0087409
3: 00:00:02.0321182
4: 00:00:02.0356848
5: 00:00:03.0459510
Which is exactly what you'd expect. Maybe your service.SaveModel
method is not implemented in a truly asynchronous fashion, and does a long-running operation before surrendering control? Here's an example of a bad implementation:
public Task SaveModel(Model model)
{
Thread.Sleep(1000);
return Task.Delay(0);
}
This makes it output:
1: 00:00:00.0000303
2: 00:00:00.0090621
3: 00:00:02.0345882
4: 00:00:03.0362871
5: 00:00:03.0365073
Upvotes: 2