2016-06-27 1 views
-3

내 웹 API 컨트롤러 <strong>MyController에</strong>에서

[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

같은 뭔가를 찾고있다 "* ** 기다려야하는 방법 **까지 ** 모든 ** ** 미리 작업 **의 마무리 *"= >'Task.WaitAll' –

+0

당신의 과제는 어떠한 결과도 반환하지 않았습니다. 당신은 어떤 결과를 기대합니까? 것들은 기다릴 수 있지만 더 이상의 결과 값이없는 간단한 Task 인스턴스입니다. 그래서 질문을 명확히하십시오 –

+0

Task.WhenAll과 Task.WaitAll의 차이점을 알고 있어야합니다. WaitAll은 무효를 반환합니다. 모든 작업이 끝나면 다음 명령문이 실행됩니다. WhenAll은 대기중인 작업을 반환합니다.작업을 기다리지 않는 한 코드는 작업 결과를 기다릴 때까지 계속됩니다. 이것은 당신이 기다리는 한 발신자가 동결하지 않는다는 장점이 있습니다. 단점은 함수를 비동기로 선언해야한다는 것입니다. 이에 대한 Stephen Cleary의 답변 : http://blog.stephencleary.com/2012/02/async-and-await.html –

답변

1

모든 작업을 사용하여 모든 작업이 완료 될 때 완료되는 새 작업을 만드는 경우 일반 비동기 패턴을 사용하여 해당 작업에서 결과를 가져올 수 있습니다.

https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenall(v=vs.110).aspx

그래서 유효성 검사 결과 문자열 // 경우 작업 [] 작업 = ... VAR 것들 =이 Task.WhenAll (작업)을 기다리고 있습니다;

WaitAll을 사용할 수도 있지만 출력 작업이 필요한 경우에는 여기를 클릭하십시오. 어쨌든 비동기 컨텍스트에 머물고있는 IMO는 항상 더 좋습니다.

https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

Task.WaitAll(tasks); 
foreach(var t in tasks) DoSomething(t.Result); 
게다가, AFAIK 차단, 현재의 thread.


더 완벽한 콘솔 예 : 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; } 
    } 
} 
+0

감사합니다. 하지만 내가 할 때 'var 작업 = 기다릴 Task.WhenAll (작업)'그것은 암시 적으로 입력 된 로컬 변수에 void를 할당 할 수 없습니다 말한다. – StrugglingCoder

+0

현재 Task []를 사용하여 작업이 무효임을 나타냅니다. 반환 된 것이 필요하면 작업 [] – Jens

+0

작업에 다양한 반환 유형이 있습니다 ... IEnumerable 에서 IEnumerable 작동 안함. – StrugglingCoder

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 . . . 
+0

'var things = Await Task.WhenAll (tasks);'암시 적으로 입력 된 로컬 변수에 void를 할당 할 수 없다는 컴파일 오류가 표시됩니다. – StrugglingCoder

+0

@StrugglingCoder 코드를 업데이트했습니다. –

0
var task1 = T1(); 
var task2 = T2(); 

await Task.WhenAll(task1, task2); 
+0

가'await Task.WhenAll (task1, task2);를 만나면 다시 다음 몇 줄로 이동하고 그 결과를 기다리지 않고 결국 반환합니다. 무엇을해야합니까? – StrugglingCoder

+0

결과를 확인하십시오 : var results = await Task.WhenAll (task1, task2); –

-1

WhenAll 완료 될 때까지 작업을 기다리지 않습니다. 그것은 비동기 적으로 수행됩니다. WaitAll 사용을 고려하는 대신

var things = Task.WaitAll(tasks); 
+0

WaitAll은 void를 반환하지만 반환 된 값이 필요합니다. – StrugglingCoder

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; 
    } 

} 
관련 문제