2015-01-28 2 views
5

글쎄, 내 문제는 Azure 저장소 테이블에 대기 table.ExecuteAsync (...) 요청한 데이터를 삽입하지만 결코 완료 내 문제입니다 (TableResult를 리턴하지 않음). InsertOrUpdate 및 Update 작업과 동일한 경우입니다. 나 또한 속성의 다른 번호와 다른 테이블을 시도 - 같은 문제.Azure 저장소 테이블 : 대기 테이블 .ExecuteAsync (InsertOperation) 실행, 끝내지 않는다

table.Execute (...)을 호출하면 모든 종류의 작업에 모두 정상적으로 작동합니다.

가 이

외부 호출 (이 비동기 행동에 MVC 컨트롤러에 위치) :

List<Task<ServiceResult<Boolean?>>> addPostTasks = new List<Task<Common.ServiceResult<bool?>>>();    
foreach (var userStream in userStreams) 
{ 
    Task<ServiceResult<Boolean?>> addPostTask = postsStorageSvc.AddImagePost(...); 
    postsAddImagePostTasks.Add(addPostTask); 
} 
Task.WaitAll(addPostTasks.ToArray()); 

방법은 전화 :

public async Task<ServiceResult<Boolean?>> AddImagePost(...) 
{ 
ServiceResult<Boolean?> result = new ServiceResult<bool?>(null); 
try 
{ 
    PostTableEntity newPost = new PostTableEntity(streamId.ToString(), Guid.NewGuid().ToString(), creatorId, date, htmlText);    
    TableOperation insertOperation = TableOperation.Insert(newPost); 
    //Following line never ends! 
    TableResult tableResult = await this._storageTableBootstrapper.Table.ExecuteAsync(insertOperation);     
    //Following line works perfect - but is not ASYNC 
    TableResult tableResult = this._storageTableBootstrapper.Table.Execute(insertOperation); 
} 
catch (Exception ex) 
{ 
    result.Result = false; 
    result.Errors.Add("AzurePostsStorageService Unexpected error: " + ex.Message); 
} 
return result; 
} 
+0

이 메서드를 어떻게 부르나요? –

+0

무엇을 의미합니까? 이 코드 블록은 비동기 메서드로, 주위의 선을 표시하도록 내 질문을 업데이트하고 있습니다. –

+0

메소드 서명과 호출 방법을 보여줍니다. 아마도 'Task.Result' 또는'Task.Wait'를 사용하여 차단하고 있습니까? –

답변

9

:

Task.WaitAll(addPostTasks.ToArray()); 

귀하의 비동기 방법은 다시 자신을 마샬링하는 시도

자세한 내용은이 문서를 참조하십시오 Task.WaitAll을 사용하여 차단 호출을 시작했기 때문에 멈춘 ASP.NET 동기화 컨텍스트

대신, 당신은 모든 방법 패턴 비동기 에 따라 그에 Task.WhenAllawait를 사용해야합니다 :

스테판 클리 어리는 @NedStoyanov 추가 자신의 블로그 게시물 (이에 정성 들여
await Task.WhenAll(addPostTasks.ToArray); 

) :

또 다른 중요한 점

:하는 ASP.NET 요청 컨텍스트 하지합니다 (UI 컨텍스트처럼)을 특정 스레드에 묶여이지만, 은 한 번에 하나의 스레드를 허용합니다.이 흥미로운 점은 공식적으로 AFAIK에 문서화되어 있지는 않지만 내 MSDN 기사 에 SynchronizationContext에 대해 언급되어 있습니다.

+2

ASP 컨텍스트에 대한 유용한 정보, 유용한 정보. –

4

이는 간단합니다 같은 - 여기

내 코드입니다 이 줄로 인해 고전 deadlock이 발생했습니다.

Task.WaitAll(addPostTasks.ToArray()); 

가로 변경합니다 : 기본적으로하여 Task.WaitAll 차단 요청 스레드

await Task.WhenAll(addPostTasks.ToArray()); 

await table.ExecuteAsync(...)에 의해 시작 Tasks의 지속을 수행 할 수 없습니다. 또 다른 방법은 SynchronizatonContext을 전환하지 않으려면 내부 작업에 ConfigureAwait(false)을 사용하는 것입니다. 원래 SynchronizationContext로 전환이 필요하지 않습니다 때마다

await table.ExecuteAsync(...).ConfigureAwait(false); 

당신은 ConfigureAwait(false) 사용할 수 있습니다. 귀하의 경우에 나는 당신이 서버에있는 것처럼 모두 기다릴 수 있다고 믿고 await 이후의 코드가 스레드 풀에서 실행되는지 여부는 중요하지 않습니다. 문제는 여기에있다 msdn.microsoft.com/enus/magazine/jj991977.aspx

+0

당신의 대답은 위와 같은 의미이지만, 처음에는 Yuval Itzchakov가 더 많은 정보를 제공해주었습니다. –

+0

예, 그의 대답이 더 좋았습니다. 나는 뭔가를 배웠다. –

+0

OK, 명확하고 케이스를 더 잘 이해하십시오. ** 실행 스택 맨 위에있는 모든 비동기 작업 (예 : table.ExecuteAsync (...) 또는 비동기 작업/메서드)에 ".ConfigureAwait (false)"를 사용 하시겠습니까? –

관련 문제