私はデータを読み取っている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メソッドをキャンセルする方法はありますか?より良いアプローチとどちらを使用する必要がありますか?
おかげ
EDIT
@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無限の待ち時間を防ぐためにタイムアウトしたいのですが、asyncは良い習慣ですが、ここでは問題はありません – dcarneiro