2017-10-04 2 views
1

를 C#으로 비 비동기에서 (화재 및 잊어 버려) 비동기 코드를 호출하는 가장 좋은 방법은 무엇 : 접근법 1과 접근법 2 사이화재를 달성하고 잊어 버리려고

class Program 
{ 
    static void Main(string[] args) 
    { 
     var my = new MyClass(); 

     my.OrderForm_Load(); 
     Console.ReadLine(); 
    } 

} 

internal class MyClass 
{ 
    //Blocking 
    public void OrderForm_Load() 
    { 
     var t1 = new ServiceTask(); 

     Task.Run(() => t1.PersistTask()); //Approach 1: 
     //[OR]    
     t1.PersistTask(); //Approach 2: Has compiler errors CS4014 
     Console.WriteLine("Second"); 
    } 
} 

internal class ServiceTask 
{ 
    //Non-Blocking 
    public async Task PersistTask() 
    { 
     var resultTask = Task.Run(() => 
     { 
      Thread.Sleep(3000); 
      Console.WriteLine("First"); 
      return Task.FromResult(0); 
     }); 

     await resultTask; 
    } 
} 

가; 나는 접근 방식 1을 선호한다. 다른 방법이 인데,은 PersistTask()를 OrderForm_Load() 메소드에서 호출하는 것이 더 좋은가? 나는 Task.Run을 사용하는 것을 주저하는 동료가 있지만 다른 더 좋은 방법이 있는지 알아 내고 싶다.

목표는 "초"를 가능한 빨리 인쇄하고 "첫 번째"를 인쇄하는 방법에 대해 걱정할 필요가 없다는 것입니다. 화재와 잊어 버려.

public async void PersistTask() 
{ 
    // no need to assign the task if you are just going to await for it. 
    await Task.Run(() => 
    { 
     Thread.Sleep(3000); 
     Console.WriteLine("First"); 
     return Task.FromResult(0); 
    }); 
} 

그리고 사용하여 전화 :

+0

정말 나쁜 화재와'공공 비동기 무효 PersistTask' –

+0

감사합니다, 당신이 PersistTask의 서명에서 무효로 작업을 대체하는 방법처럼, 잊어 버려이 들어

Thread.Sleep(3000); 

을 : 그래서,이를 변경합니다. 그러나 질문은 OrderForm_Load() 메소드에서 PersistTask를 호출하는 가장 좋은 방법입니다. –

+0

그게 내가 대답을 게시하지 않은 이유입니다. 나는 또한 조용한 충돌로 인해서 정말 나쁜 것임을 잊어 버렸다. –

답변

3

fire and forget 방법을 달성하는 가장 좋은 방법은 async void 수정에 있습니다

//Blocking 
public void OrderForm_Load() 
{ 
    var t1 = new ServiceTask(); 

    Task.Run(() => t1.PersistTask()); //Approach 1 
    //[OR]    
    t1.PersistTask(); //Approach 2 
    Console.WriteLine("Second"); 
} 

다른 차이가있다,하지만 : Task.Run는 바인딩 CPU에 가장 적합 행동 양식. 자세한 내용은 in this answer을 참조하십시오.
또한 비동기 작업에서 동기 대기를 사용하지 않는 것이 좋습니다.

Task.Delay(3000); 
+0

감사합니다. PersistTask는 I/O 작업을 모방 한 것입니다. 가 기다리고 Task.Run (() => { 에 Thread.sleep (3000); Console.WriteLine ("최초"); 창 Task.FromResult (0)} ); 또는 과제를 할당하는 것이 문제는 아니지만 어떤 접근 방식이 더 좋을까요? 지금까지 제가 읽은 것과 당신이 제안한 것은 Task.Run입니다. –