在我的Web API控制器 MyController 中,调用了我的服务类
[HttpPost]
Route("groupmembershipvalidate")]
public IHttpActionResult PostGroupMembershipValidate(ListGroupMembershipUploadInput ListGroupMembershipUploadInput)
{
//perform some tasks
var searchResults = ts.validateDetails(gmvi);
return Ok(searchResults);
}
现在这个 validateDetails 服务类需要并行运行某些任务,需要等待所有结果返回,然后才返回。
var tasks = new Task[]
{
Task.Factory.StartNew(() => gd.validateChapterCodeDetails(_input1)),
Task.Factory.StartNew(() => gd.validateGroupCodeDetails(_input1)),
Task.Factory.StartNew(() => gd.validateMasterIdDetails(_input1))
};
var things = Task.WhenAll(tasks);
//Some tasks
return result;
在所有任务返回结果之前,不会计算返回的结果。但是当Task.WhenAll(任务)被命中时,它会立即移动到接下来的几行并返回 PostGroupMembershipValidate 控制器方法。
如何在返回值之前等待并在获取所有值后才返回?
答案 0 :(得分:1)
如果可以使用all创建一个新任务,该任务在其中的所有任务完成时完成,则可以使用常规异步模式继续从该任务中提取结果。
https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenall(v=vs.110).aspx
所以 //如果您的验证结果是字符串: 任务[]任务= ... var things = await Task.WhenAll(tasks);
或者可以使用WaitAll,但是如果你需要在输出上做这个笨拙的方法。无论如何,留在异步环境中的IMO总是更好。
Task.WaitAll(tasks);
foreach(var t in tasks) DoSomething(t.Result);
https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx
此外,它会阻止当前的线程AFAIK。
更完整的控制台示例: https://dotnetfiddle.net/JMLHxR
using System;
using System.Threading.Tasks;
public class Program
{
private static int counter = 0;
public static void Main()
{
Random rnd = new Random();
var tasks = new Task<object>[]
{
// If your target method returns a task.
// - note: A Proxy or similar approach will probably be more readable.
CreateTask(rnd.Next(500,2000)).ContinueWith(t => (object)t.Result),
CreateOtherTask(rnd.Next(500,2000)).ContinueWith(t => (object)t.Result),
CreateTask(rnd.Next(500,2000)).ContinueWith(t => (object)t.Result),
CreateOtherTask(rnd.Next(500,2000)).ContinueWith(t => (object)t.Result),
//If your target method is syncronious.
Task.Run(() => (object)CreateSimple()),
Task.Run(() => (object)CreateMessage()),
Task.Run(() => (object)CreateSimple()),
Task.Run(() => (object)CreateMessage())
};
Task.WaitAll(tasks);
foreach(var t in tasks)
Console.WriteLine(t.Result);
// They are already completed here, but just to show the syntax.
// .Result should obvisously be awaited instead.
var all = Task.WhenAll(tasks).Result;
foreach(var result in all)
Console.WriteLine(result);
}
private static string CreateSimple()
{
int id = Program.counter++;
return "Task [" + id + "] delayed: NONE";
}
private static Message CreateMessage()
{
return new Message(CreateSimple());
}
private static async Task<string> CreateTask(int delay)
{
int id = Program.counter++;
await Task.Delay(delay);
return "Task [" + id + "] delayed: " + delay;
}
private static async Task<Message> CreateOtherTask(int delay)
{
int id = Program.counter++;
await Task.Delay(delay);
return new Message("Task [" + id + "] delayed: " + delay);
}
public class Message {
private string message;
public Message(string msg) { message = msg; }
public override string ToString(){ return message; }
}
}
答案 1 :(得分:1)
您正在寻找类似的东西
public class Sample1
{
public void Run()
{
foreach ( var item in Validate( "foobar" ).Result )
{
Console.WriteLine( item );
}
}
// starts some result producing tasks
// await all of them
// return the result of each task
public async Task<IEnumerable> Validate( string input )
{
var tasks = new Task<object>[ ] {
Task.Run( ()=> (object) ValidateFoo(input) ),
Task.Run( ()=> (object) ValidateBar(input) ),
};
return await Task.WhenAll( tasks );
}
private string ValidateFoo( string input )
{
return "foo";
}
private bool ValidateBar( string input )
{
return true;
}
}
答案 2 :(得分:0)
static void Main(string[] args)
{
Console.WriteLine("Started");
Task.WaitAll(task1(), task2());
Console.WriteLine("Ended");
}
static async Task<string> task1()
{
Console.WriteLine("Started task1");
var task = await Task.Run(() => { return "task1"; });
Console.WriteLine("Ended task1");
return task;
}
static async Task<string> task2()
{
Console.WriteLine("Started task2");
var task = await Task.Run(() => { return "task2"; });
Console.WriteLine("Ended task2");
return task;
}
}
生成此输出:
Started
Started task1
Ended task1
Started task2
Ended task2
Ended
Press any key to continue . . .
答案 3 :(得分:0)
var task1 = T1();
var task2 = T2();
await Task.WhenAll(task1, task2);