我正在尝试使用以下代码,但在发生异常时它不起作用。任何人都可以帮我解决这个问题吗?我试图在fetchresponse()。catch()中抛出Web异常。是否有可能返回diff类型的数据(不仅仅是一个字符串输出)。
IObservable<string> tempReturnData = null;
try
{
// create http web request
HttpWebRequest WSrequest = (HttpWebRequest)WebRequest.Create(WebURL);
// instantiate Request class object
RequestState rs = new RequestState();
rs.Request = WSrequest;
// Lock current webrequest object.. incase of retry attempt
lock (WSrequest)
{
rs.Request.ContentType = "application/x-www-form-urlencoded";
rs.Request.Method = "POST";
rs.Request.Timeout = 100;
// bug in .net that closes the connection prior to it being finished
rs.Request.KeepAlive = false;
rs.Request.ProtocolVersion = HttpVersion.Version10;
// async pattern get request
var fetchRequestStream = Observable.FromAsyncPattern<Stream>(rs.Request.BeginGetRequestStream, rs.Request.EndGetRequestStream);
// async pattern get response
var fetchResponse = Observable.FromAsyncPattern<WebResponse>(rs.Request.BeginGetResponse, rs.Request.EndGetResponse);
//
tempReturnData = (from tempResult in fetchRequestStream() select tempResult).SelectMany(stream =>
{
using (var writer = new StreamWriter(stream)) writer.Write(postData);
// here i wants to catch web exception in fetchResponse() FYI : in my function i am returning IObservable<string>
return fetchResponse().Catch(Observable.Empty<WebResponse>()).Retry(5);
}).Select(result =>
{
lock (rs)
{
rs.Response = (HttpWebResponse)result;
string s = "";
// if response is ok then read response stream data
if (rs.Response.StatusCode == HttpStatusCode.OK)
{
using (StreamReader reader = new StreamReader(rs.Response.GetResponseStream())) s = reader.ReadToEnd();
}
// Error case if error occurs then try after random time period
else
{
if (Attempt < appConfig.PSPRequestAttempt)
{
Attempt++;
RandomisePost(WebURL, postData, Attempt);
}
}
return s;
}
}); // get response stream data
return tempReturnData;
}
}
catch (Exception ex)
{
// Debug.WriteLine("Exception Occurs " + ex.Message);
return null;
}
答案 0 :(得分:2)
我认为你很难将Rx和非Rx代码混合在一起。尝试使用这样的简单Rx查询来使您的Rx代码工作:
return
from st in fetchRequestStream()
from rp in postDataAndFetchResponse(st)
from s in fetchResult(rp)
select s;
此查询依赖于三个如下所示的函数:Func<X, IObservable<Y>>
。
然后,您可以使用标准RX运算符处理所有重试和异常处理。无需做任何时髦的“随机”电话!
您可以这样称呼它:
FetchStringFromPost("url", "postData")
.Retry(3)
.Subscribe(s => { }, ex =>
{
/* Exceptions here! */
}, () => { });
这是完整的代码:
public IObservable<string> FetchStringFromPost(string WebURL, string postData)
{
var request = (HttpWebRequest)WebRequest.Create(WebURL);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = 100;
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
var fetchRequestStream = Observable
.FromAsyncPattern<Stream>(
request.BeginGetRequestStream,
request.EndGetRequestStream);
var fetchResponse = Observable
.FromAsyncPattern<WebResponse>(
request.BeginGetResponse,
request.EndGetResponse);
Func<Stream, IObservable<HttpWebResponse>> postDataAndFetchResponse = st =>
{
using (var writer = new StreamWriter(st))
{
writer.Write(postData);
}
return fetchResponse().Select(rp => (HttpWebResponse)rp);
};
Func<HttpWebResponse, IObservable<string>> fetchResult = rp =>
{
if (rp.StatusCode == HttpStatusCode.OK)
{
using (var reader = new StreamReader(rp.GetResponseStream()))
{
return Observable.Return<string>(reader.ReadToEnd());
}
}
else
{
var msg = "HttpStatusCode == " + rp.StatusCode.ToString();
var ex = new System.Net.WebException(msg,
WebExceptionStatus.ReceiveFailure);
return Observable.Throw<string>(ex);
}
};
return
from st in fetchRequestStream()
from rp in postDataAndFetchResponse(st)
from s in fetchResult(rp)
select s;
}
当我测试上面的代码时,我试着打电话给FetchStringFromPost("http://www.microsoft.com", "foo").Materialize()
并取回了这个:
似乎像对待一样工作。让我知道你是怎么走的。