我的 MVC 4.0 应用程序中有一个奇怪的问题。我使用 REST Web 服务(Amazon Associate)。我创建了一种方法,我可以在任何地方使用它。缩短版是这样的:
private async Task<XElement> GetRequest(string url)
{
string myresponse;
HttpResponseMessage response = null;
HttpClient client = new HttpClient();
try
{
response = await client.GetAsync(url);
myresponse = response.Content.ToString();
if (myresponse.Contains("503"))
{
myTrace.WriteLine("503 Sleep.....");
Thread.Sleep(3000); // looks like amazon us does not like fast requests....
return await GetRequest(url); //restart after pausing....
}
}
catch (TaskCanceledException ex)
{
myTrace.WriteLine("TaskCancelled From GetRequest: " + ex);
return null;
}
catch (HttpRequestException ex)
{
myTrace.WriteLine("RequestException Sleep.....");
Thread.Sleep(300000); // 5 minutes de pause
}
catch (Exception ex)
{
myTrace.WriteLine("From GetRequest: " + ex);
return null;
}
try
{
XElement content = await response.Content.ReadAsAsync<XElement>();
response.Dispose();
client.Dispose();
return content;
}
catch (Exception)
{
return null;
}
}
没什么特别的,它确实工作得很好....但是,现在,在特定的呼叫中,它会爆炸client.GetAsync(url)
。起初我怀疑 url 中的某些内容是错误的,所以我从调试器会话中抓取它并将其直接粘贴到我的浏览器中,得到了预期的答案......
因此,URL 没有任何问题。做了一个小单元测试,使用相同的特定 URL 就可以了...
当它在调试器中爆炸时,很难看出有什么问题。(没有抛出异常!)。最后,我通过 IntelliTrace 看到有异常,似乎在System.Threading.Tasks
. 很难确定,因为调用堆栈对于我的非专家眼来说有点令人困惑......
这是我从之前的代码中获得的调用堆栈:
> System.Web.dll!System.Web.ThreadContext.AssociateWithCurrentThread(bool setImpersonationContext = {unknown}) C#
System.Web.dll!System.Web.HttpApplication.OnThreadEnterPrivate(bool setImpersonationContext = {unknown}) C#
System.Web.dll!System.Web.HttpApplication.OnThreadEnter() C#
System.Web.dll!System.Web.HttpApplication.System.Web.Util.ISyncContext.Enter() C#
System.Web.dll!System.Web.Util.SynchronizationHelper.SafeWrapCallback(System.Action action = {unknown}) C#
System.Web.dll!<>c__DisplayClass9.AnonymousMethod(System.Threading.Tasks.Task _ = {unknown}) C#
mscorlib.dll!System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke() C#
mscorlib.dll!System.Threading.Tasks.Task.Execute() C#
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj = {unknown}) C#
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext = {unknown}, System.Threading.ContextCallback callback = {unknown}, object state = {unknown}, bool preserveSyncCtx = {unknown}) C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext = {unknown}, System.Threading.ContextCallback callback = {unknown}, object state = {unknown}, bool preserveSyncCtx = {unknown}) C#
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = {unknown}) C#
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution = {unknown}) C#
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() C#
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() C#
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() C#
无论如何,这看起来肯定与任务、异步、后台工作人员等有关......有没有一种好方法可以“清除”所有其他正在运行的任务,以避免这个问题?
谢谢你的帮助,伯纳德。