2

나는 다음과 같은 코드가 있습니다비동기 작업

public async Task SendPushNotificationAsync(string username, string message) 
{ 
    var task = ApnsNotifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, username); 
    if (await Task.WhenAny(task, Task.Delay(500)) == task) { 
     return true; 
    } 
    return false; 
} 

내가 SendAppleNativeNotificationAsync이 (결코 포함하는 방법 중 반환하지 않음) 무기한 매달려 있었다, 그래서 나는 그것은 500ms 후 취소하라는 시도 것으로 나타났습니다합니다. 하지만 여전히 ... WhenAny에 대한 호출이 중단되고 return이 무의식적으로 대기하는 소비자를 발생시킵니다.이 비동기 메소드를 호출하는 동기화 메소드이므로 .Wait()을 호출합니다.

_commService.SendPushNotificationAsync(user.Username, notificationDto.PushContent).Wait(TimeSpan.FromSeconds(1)); 

설정 시간이 지난 후에 어떻게 강제 종료합니까?

작업을 수행하는 대신 await 대신 간단히 "실행 및 삭제"하면 어떻게됩니까?

+0

어디에서이 코드를 실행합니까? 내 말은, 웹 애플리케이션, 데스크톱 애플리케이션, 아마도 모바일 일까? – Evk

+0

@Evk 이것은 WebApi 컨트롤러에서 호출하는 동기화 서비스 메서드에서 호출 된 서비스 메서드에 있습니다. – SB2055

+2

"UI"또는 "요청"스레드가있는 환경에서 Wait (또는 Task.Result)를 async \ await과 함께 사용하지 마십시오. 사용자가 관찰하는 것처럼 교착 상태가됩니다. – Evk

답변

5

는이 비동기 메소드를 호출 동기화 방법, 그래서 나는 .Wait()를 호출

그리고 그 문제입니다. 당신은 deadlocking because you're blocking on asynchronous code입니다.

이를위한 가장 좋은 방법은 Wait 대신 await을 사용하는 것입니다

await _commService.SendPushNotificationAsync(user.Username, notificationDto.PushContent); 

당신이 절대적으로하지 사용 await, 그럼 당신은 내 Brownfield Async article에 설명 된 해킹 중 하나 시도 할 수 있습니다 할 수 있습니다.

+0

감사합니다. 'await'을 사용하고'SendAppleNativeNotificationAsync'가 결코 돌아 오지 않는다면 괜찮을까요? – SB2055

+0

@ SB2055 : 왜 결코 돌아 오지 않을까요? –

+0

나는 디버거에서 볼 수있는 동작에 근거하고있다. 나는'return'을 잡을 수는 없지만, 다른 스레드가 그것을 잡아 먹고 있기 때문에 가능할 수도있다. – SB2055