HttpWebResponse.GetResponseStream()
에서 데이터를 읽는 스트림이 나타납니다. 이제 Timeout
속성을 구현하고 싶습니다. 가장 쉬운 방법은 stream.ReadTimeout = timeout
이지만 InvalidOperationException -> Timeouts are not supported on this stream
을 던집니다.스트림 읽기에서 시간 초과 속성 구현
이 점을 감안할 때, 나는 timeout 속성을 직접 구현하려고하지만 dispose에 매달렸다. 이 코드
public class MyStream : Stream {
private readonly Stream _src;
public override int ReadTimeout { get; set; }
public MyStream (Stream src, int timeout) {
ReadTimeout = timeout;
_src = src;
}
public override int Read(byte[] buffer, int offset, int count) {
var timer = new AutoResetEvent(false);
int read = 0;
ThreadPool.QueueUserWorkItem(
_ => {
read = _src.Read(buffer, offset, count);
timer.Set();
});
bool completed = timer.WaitOne(ReadTimeout);
if (completed) {
return read;
}
throw new TimeoutException(string.Format("waited {0} miliseconds", ReadTimeout));
}
문제는 이후 제대로 어딘가에서 처리되고있는 TimeoutException
가 발생합니다 : 이것은 내가 지금까지 무엇을 가지고 있습니다. _src 스트림이 삭제되었다는 것을 나타내는 _src.Read(buffer, offset, count)
에 예외가 발생합니다.
ThreadPool 메서드를 취소 할 수있는 방법이 있습니까? 아니면 더 나은 접근 방법을 사용해야합니까? @JotaBe에 의해 요청대로였다
감사
편집 내가 HttpWebResponse 클래스에서 스트림을 얻을 코드입니다 :
_httpRequest = WebRequest.CreateHttp(url);
_httpRequest.AllowReadStreamBuffering = false;
_httpRequest.BeginGetResponse(
result =>
{
try {
_httpResponse = (HttpWebResponse)_httpRequest.EndGetResponse(result);
stream = _httpResponse.GetResponseStream();
}
catch (WebException) {
downloadCompleted.Set();
Abort();
}
finally {
downloadCompleted.Set();
}
},
null);
bool completed = downloadCompleted.WaitOne(15 * 1000);
if (completed) {
return new MyStream(stream, 10000);
}
['Stream.BeginRead'] (http://msdn.microsoft.com/en-us/library/system.io.stream.beginread (v = vs.95) .aspx를 사용할 수 있습니다.) 'IAsyncResult'의'AsyncWaitHandle' 속성을 사용하여 수동으로 롤오버하기보다는 기다려야합니다. – vcsjones
당신이이 길을 너무 멀지 않고 대안을 탐험 할 수 있다면 Reactive Extensions (Rx)를 사용하면 이런 종류의 일이 사소하다는 것을 알게되었습니다. codeplex에 WP7Contrib 프로젝트도 있습니다. 그것은 당신이 활용할 수있는 모든 Rx를 기반으로하는 전체 네트워크 통신 측면을 가지고 있습니다. – Alex
@vcsjones 무한 대기 시간을 방지하기 위해 제한 시간을 원하지만 비동기가 좋은 방법이지만 문제는 없습니다 – dcarneiro