延迟开始任务<T>
Defer starting of a Task<T>
我有一系列方法(参数数量可变)return一个任务
我想通过传递任务创建一个方法,在每个方法之前和之后做一些事情。
我已经简化了这个示例中的所有内容(删除了 cancellationToken、实际处理等):
public async Task<string> GetDataString()
{
Console.WriteLine("Executing");
return "test";
}
public async Task<T> Process<T>(Task<T> task)
{
Console.WriteLine("Before");
var res = await task;
Console.WriteLine("After");
return res;
}
我的主要观点是:
Task<string> task = GetDataString();
string result = await Process<string>(tasks);
Console.WriteLine(res);
控制台输出是
Executing
Before
After
test
我可以做些什么来创建任务但实际上并没有启动它?并且只在等待之前启动它?
我设法通过创建一个 PauseToken 来做到这一点,如本文所述:
https://devblogs.microsoft.com/pfxteam/cooperatively-pausing-async-methods/
但是不知道有没有更好的办法
谢谢,
马蒂亚
您的通用 ProcessAsync
方法可以接受任务工厂作为参数:
public async Task<T> ProcessAsync<T>(Func<Task<T>> taskFactory)
{
Console.WriteLine("Before");
var res = await taskFactory();
Console.WriteLine("After");
return res;
}
这样,将在您调用工厂方法时创建任务。您可以控制它的创建。
下面是调用 ProcessAsync
方法的示例,将 lambda 作为工厂传递:
var result = await ProcessAsync(() => GetDataStringAsync(arg1, arg2));
这样你就不会局限于没有参数的工厂方法。
为了完整起见,我应该提到 Task
对象也可以使用构造函数 new Task()
在冷状态下创建,然后使用 Start
方法开始,但这种方法不是推荐。
您可以删除 async 关键字(来自 GetDataString)并创建一个将在您等待时执行的新任务
所以下面代码的结果是:之前,执行,测试,之后
private static async Task Start()
{
Task<string> task = GetDataString();
string result = await Process<string>(task);
Console.WriteLine(result);
Console.ReadLine();
}
public Task<string> GetDataString()
{
return new TaskFactory(TaskScheduler.Default).StartNew(() =>
{
Console.WriteLine("Executing");
return "test";
});
}
public async Task<T> Process<T>(Task<T> task)
{
Console.WriteLine("Before");
var res = await task;
Console.WriteLine("After");
return res;
}
我有一系列方法(参数数量可变)return一个任务 我想通过传递任务创建一个方法,在每个方法之前和之后做一些事情。 我已经简化了这个示例中的所有内容(删除了 cancellationToken、实际处理等):
public async Task<string> GetDataString()
{
Console.WriteLine("Executing");
return "test";
}
public async Task<T> Process<T>(Task<T> task)
{
Console.WriteLine("Before");
var res = await task;
Console.WriteLine("After");
return res;
}
我的主要观点是:
Task<string> task = GetDataString();
string result = await Process<string>(tasks);
Console.WriteLine(res);
控制台输出是
Executing
Before
After
test
我可以做些什么来创建任务但实际上并没有启动它?并且只在等待之前启动它?
我设法通过创建一个 PauseToken 来做到这一点,如本文所述: https://devblogs.microsoft.com/pfxteam/cooperatively-pausing-async-methods/ 但是不知道有没有更好的办法
谢谢, 马蒂亚
您的通用 ProcessAsync
方法可以接受任务工厂作为参数:
public async Task<T> ProcessAsync<T>(Func<Task<T>> taskFactory)
{
Console.WriteLine("Before");
var res = await taskFactory();
Console.WriteLine("After");
return res;
}
这样,将在您调用工厂方法时创建任务。您可以控制它的创建。
下面是调用 ProcessAsync
方法的示例,将 lambda 作为工厂传递:
var result = await ProcessAsync(() => GetDataStringAsync(arg1, arg2));
这样你就不会局限于没有参数的工厂方法。
为了完整起见,我应该提到 Task
对象也可以使用构造函数 new Task()
在冷状态下创建,然后使用 Start
方法开始,但这种方法不是推荐。
您可以删除 async 关键字(来自 GetDataString)并创建一个将在您等待时执行的新任务
所以下面代码的结果是:之前,执行,测试,之后
private static async Task Start()
{
Task<string> task = GetDataString();
string result = await Process<string>(task);
Console.WriteLine(result);
Console.ReadLine();
}
public Task<string> GetDataString()
{
return new TaskFactory(TaskScheduler.Default).StartNew(() =>
{
Console.WriteLine("Executing");
return "test";
});
}
public async Task<T> Process<T>(Task<T> task)
{
Console.WriteLine("Before");
var res = await task;
Console.WriteLine("After");
return res;
}