我正在遍历大量对象(1503)并在我编写的 ServiceProxy 上调用 save 方法。服务代理使用 Silverlight 4 中的新网络堆栈调用 BeginGetRequestStream 以启动将我的对象异步发送到我为保存对象而编写的 azure REST 服务的过程。我使用的 Http 方法是 POST。我知道 HttpWebClient 足够聪明,可以重用 Http 连接,所以我不会同时打开到服务器的 1503 连接。保存工作正常,所有 1503 个对象都保存得非常快。但是,当我再次尝试保存相同的对象时,我希望收到一个禁止的 HttpStatus 代码,因为这些对象已经存在,并且这是我设置我的天蓝色 Web 服务返回的代码。在小对象组上,它按预期工作。然而,
System.Exception ---> System.Exception:Error HRESULT E_FAIL has been returned from a call to a COM component.
at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)...
我想知道我是否应该在我忽略的 HttpWebClient 实例上执行某种簿记或维护,这就是导致 http 错误引发异常的原因,但新的保存可以完美地工作。这是我处理错误情况的代码:
private static void SendAncestorResponseCallback(IAsyncResult result)
{
var info = (SendAncestorInfo)result.AsyncState;
try
{
var response = info.Request.EndGetResponse(result);
info.Response = response;
}
catch ( Exception ex)
{
info.Error = ex;
}
info.MainThreadContext.Post(SendAncestorMainThreadCallback, info);
}
private static void SendAncestorMainThreadCallback(object state)
{
var info = (SendAncestorInfo)state;
IAncestor origAncestor = info.Content;
HttpWebResponse response = null;
if (info.Error != null)
{
if ((info.Error as WebException) == null)
{
info.Callback(false, origAncestor, null, info.Error);
return;
}
else //get response from WebException
{
response = (HttpWebResponse)(info.Error as WebException).Response;
}
}
else //get response from info.Response
{
response = info.Response as HttpWebResponse;
}
if (response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.Forbidden)
{
var stream = response.GetResponseStream();
using (var reader = new StreamReader(stream))
{
IAncestor retAncestor = XMLSerializerHelper.DeserializeObject<Ancestor>(reader.ReadToEnd());
info.Callback(response.StatusCode == HttpStatusCode.Created, origAncestor, retAncestor, null);
}
}
else info.Callback(false, origAncestor, null, info.Error);
}
考虑到 Web 服务是如何编写的,我应该只期望创建或禁止的 http 状态代码,就像我对小组所说的那样。我只是开始收到前面提到的错误这一事实让我觉得我在 HttpWebRequest 对象等方面做错了。任何帮助将不胜感激。谢谢。
--update 这里是生成 HttpWebRequest 的代码:
foreach (IAncestor ancestor in ancestors)
{
AncestorViewModel ancestorVM = new AncestorViewModel(ancestor);
ancestorVM.Status = SaveStatus.Undefined;
ParsedAncestors.Add(ancestorVM);
_service.CreateAncestor(UserSrc, ancestor, (success, origAncestor, retAncestor, exception) =>
{
AncestorViewModel result = ParsedAncestors.First(a => a.Model.IdNo == origAncestor.IdNo);
if (exception == null)//web response was either Created or Forbidden
{
if (success)//Ancestor successfully created
{
savedAncestors++;
SuccessMessage = string.Format("{0} Saved\n", savedAncestors);
result.Status = SaveStatus.Saved;
}
else //Ancestor already existed
{
conflictAncestors.Add(origAncestor, retAncestor);
ConflictMessage = string.Format("{0} Conflicts\n", conflictAncestors.Count);
result.Status = SaveStatus.Conflicted;
}
}
else //Show exception recieved from remote web service
{
//if (exception as WebException != null)
//{
// //if exception is WebException get status code and description
// HttpWebResponse rs = (HttpWebResponse)(exception as WebException).Response;
// Message += string.Format("WebServer returned status code {0}: '{1}'\n", (int)rs.StatusCode, rs.StatusDescription);
//}
errors.Add(origAncestor, exception);
ErrorMessage = string.Format("{0} Errors\n", errors.Count);
result.Status = SaveStatus.Error;
}
});
}
public void CreateAncestor(string userSrc, IAncestor ancestor, Action<bool, IAncestor, IAncestor, Exception> callback)
{
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
var request = (HttpWebRequest)WebRequest.Create(
new Uri(string.Format("{0}/{1}/{2}", rootUri, AncestorsRestPoint, userSrc)));
request.Method = "POST";
request.ContentType = "application/xml";
var info = new SendAncestorInfo
{
Request = request,
Callback = callback,
Content = ancestor,
MainThreadContext = SynchronizationContext.Current
};
request.BeginGetRequestStream(SendAncestorRequestCallback, info);
}