2015-01-28 4 views
0

내가 여러 스레드에 의해 병렬로 실행되는 다음 코드 조각, 한 :스트림이 읽기/쓰기로 인해 교착 상태가 발생합니까?

private delegate Stream MyDelegate(string url); 

private IAsyncResult BeginRequest(AsyncCallback callback, object state) 
{ 
    return ((MyDelegate)QuerySync).BeginInvoke(url, callback, state); 
} 

private Stream EndRequest(IAsyncResult result) 
{ 
    return ((MyDelegate)((AsyncResult)result).AsyncDelegate).EndInvoke(result); 
} 

private Stream QuerySync(string url) 
{ 
    return (this.client).GetHttpWebResponse(url).GetResponseStream(); 
} 

public async Task<Stream> GetResponseStream(string url){  
    using (Stream input = await Task<Stream>.Factory.FromAsync(BeginRequest, EndRequest, url, null).ConfigureAwait(false)) 
    { 
     var output = new MemoryStream(); 
     await input.CopyToAsync(output).ConfigureAwait(false); 
     output.Position = 0; 
     return output; 
    } 
} 

그리고, 어떤 이유로, 응용 프로그램이 산발적으로 내하면 GetResponseStream() 메서드 내 중지가 (예외가 발생하지, 그것은 중단을 justs 영원히). 나는 가능한 원인을 찾아 보았고 동일한 스트림에서 병렬로 읽고 쓰려고 할 때 교착 상태가 발생할 수 있음을 알았다. 문제는, 실제로 읽고 쓰는 것이 아닙니다. 스트림 (적어도 그렇게 생각합니다)입니다. 왜냐하면 CopyToAsync (분명히 내부적으로이 스트림에 대한 읽기를 수행)를 호출하기 전에 입력 스트림에 쓰는 최근에 생성 된 작업을 기다리고 있기 때문에 읽기가 끝나면 읽기만 시작됩니다. 그래서 나는 같은 스트림에서 동시에 읽고 쓰지 않기 때문에 이것이 왜 교착 상태를 일으키는 지 알지 못한다.

중요한 점은 모르겠지만 부수적으로, 내 QuerySync 메서드는 완전히 동기식입니다. 응답을 얻기 위해 사용하는 클라이언트가 현재 비동기 요청을 지원하지 않기 때문입니다.

+0

여러 스레드에서 동시에 클라이언트의 응답으로 스트림을 가져 오는 것은 나쁜 생각처럼 들릴 수 있습니다. 클라이언트가 응답 스트림을 동시에 읽는 다중 스레드를 갖도록 설계된 것을 기대하지는 않을 것입니다. 이것이 바로 당신이하는 일입니다. 병렬로 여러 작업을 수행하려면 하나의 스레드가 데이터를 읽고이를 데이터 구조에 넣은 후에 여러 스레드에 노출 시키려면 여러 클라이언트를 작성하십시오. – Servy

+0

@Servy : 코드를 단순화하려고했지만 중요한 요구 사항을 생략했습니다. (명확히하기 위해 편집 됨) - GetResponseStream에 대한 각 호출은 클라이언트에 전달되는 URL을 제공하므로 각 호출은 실제로 다른 응답에 해당하므로, 따라서 데이터를 한 번 읽은 다음 노출 할 수는 없습니다. 또한 여러 클라이언트를 만들면 너무 많은 오버 헤드가 추가되어 응용 프로그램의 성능이 저하됩니다. –

+0

음, 스레드가 안전하지 않기 때문에 교착 상태가 발생하는 "고성능"응용 프로그램이나 실제로 올바르게 작동하는 "성능이 떨어지는 응용 프로그램"을 하나 선택하십시오. – Servy

답변

0

이러한 요청을 수행하는 데 사용중인 클라이언트는 여러 스레드에서 동시에 액세스하도록 설계되지 않았습니다. 별도의 스레드에서 액세스하지 못하도록 여러 클라이언트를 만들어야합니다.