2014-12-19 9 views
0

함수 A가보다 긴 비동기 메서드 B (웹 서비스 호출 포함)를 시작해야한다는 요구 사항이 있습니다.비동기 작업 .Net 4.5

함수 B가 아직 반환되지 않은 경우에도 함수 A는 반환해야합니다.

기능 B는 데이터를 반환하지 않으며, 최상의 코드는 무엇을 할 것, 기능 A가 닷넷 4.5 C#을 사용

를 반환했습니다 부르고 경우에도 실행해야하고, 당신은 어떤 스레딩 문제를을 forsee 수 있습니까?

.net에는 많은 예제가 있지만 목적을 위해 코드를 찾는 것은 그렇게 간단하지 않습니다.

public void A() 
{ 
    // Do something... 

    Task.Run(B); 
    // or, if you need to pass arguments to B: 
    // Task.Run(() => B(x, y, z)); 

    // Do something else... 
} 

public void B() 
{ 
    // Do something... 
} 

것은 예외가 B에서 던져 질 수 있도록하기 위해, 또는 프로세스를 충돌합니다 않도록주의 :

답변

1

함수 A가 아직 반환되지 않은 경우에도 함수 A는 반환해야합니다.

이 경우 핵심은 awaitB에 대한 호출이 아니어야한다는 것입니다.

더 긴 실행 비동기 메서드 B (웹 서비스 호출 포함)를 시작합니다. 작업의 대부분은 웹 서비스 호출이있는 경우 일반적으로

, 당신이해야 하지 사용 Task.Run. Task.Run은 비동기 IO를 사용할 수 있기 때문에 필요하지 않은 백그라운드 스레드에서 작업을 실행합니다.

대신 async Task B() 메서드를 만들고 메서드 내에서 await 메커니즘을 사용하고 호출하십시오. 기본적으로 컴파일러 경고가 발생하지만 발생하는 예외를 기록하는 FireAndForget 확장 메서드를 만들어 해결할 수 있습니다.

public static async void FireAndForget(this Task task) 
{ 
    try 
    { 
     await task; 
    } 
    catch (Exception e) 
    { 
     // Log the exception 
    } 
} 

이것은 또한 B() 내에서 발생하는 로그 문제의 혜택을 제공 :로

은 간단 할 수있다.

+0

로그 할 수 있다는 이점은 큰 보너스입니다 ! –

+0

Reed, 임 귀하의 확장 방법을 사용하지만 그것은 단지 기다리고있는 작업에 매달려 있습니다. 의도 한대로 사용하고 있습니까? var t = 새 작업 (() => DoStuff() t.FireAndForget(); –

+0

t.FireAndForget()이 실행되기 전에 t.Start()에 호출을 추가하면 .. –

1

가장 쉬운 방법은 새로운 스레드에서 작업을 실행 Task.Run을 사용하는 것입니다.

+0

매우 간단합니다! B가 끝나기 전에 A가 돌아 오더라도이 작업이 가능합니까? –

+0

@SteveWard, 예; 'Task.Run'은 즉시 반환되고 B는 별도의 스레드에서 계속 실행됩니다. –

+1

나는 OP가 웹 서비스 호출 (비동기 IO)을 사용하고 있다고 지적한 이래로 이것이 꼭 대단한 사례는 아니라고 주장하고 싶다. –