HttpRequestMessage在发送请求后被处理掉

时间:2018-05-02 21:34:21

标签: c#

我的程序中有一个类调用API,每个请求都会通过以下函数在超时的情况下重试请求几次。

            private readonly ISubjectService _subjectService;

            public TeacherController(ISubjectService subjectService)
            {
                _subjectService= subjectService;
            }

     [HttpPost]
            public IActionResult AddNewSubjects(IEnumerable<Subject> subjects)
            {
                var newSubjects= (from p in subjects
                                    where p.State== Status.New
                                    select p);
                    var result = _subjectService.SaveTeacherSubjects(newSubjects);
                return View("ProfesorPages");   
            }

出于某种原因,虽然我得到一个protected async Task<HttpResponseMessage> RetryIfExceptionAsync(string urlString, HttpMethod httpMethod, HttpContent httpContent, byte exceptionRetries) { HttpResponseMessage httpResponse = null; byte retries = exceptionRetries; while (retries != 0) { var httpRequest = new HttpRequestMessage() { RequestUri = new Uri(urlString), Method = httpMethod, Content = httpContent }; try { httpResponse = await Program.HttpClient.SendAsync(httpRequest); // <--- This is line 93 } catch (TaskCanceledException taskCanceledException) { if (!taskCanceledException.CancellationToken.IsCancellationRequested) { Program.TimeoutDebugLog.Append(String.Format("{0} timeout, retries: {1}, url: {2}", httpMethod, retries, urlString)); //TimeoutDebugLog is a StringBuilder await Task.Delay(200); retries--; continue; } } break; } if (httpResponse == null) { using (var stream = new System.IO.FileStream("TimeoutDebugLog.txt", System.IO.FileMode.Append)) using (var writer = new System.IO.StreamWriter(stream)) { writer.Write(Program.TimeoutDebugLog.ToString()); } Program.TimeoutDebugLog.Clear(); throw new CustomHttpRequestException("Failed to obtain response after 5 attemps") { RequestUrl = urlString, RequestMethod = httpMethod, RequestContent = httpContent.ReadAsStringAsync().Result }; } else { return httpResponse; } } 说“不可能访问discarted object objectname:System.Net.Http.StringContent”。这是指向在第93行抛出异常的堆栈跟踪,我已在代码中指出:

ObjectDiposedException

我已经检查了the HttpClient source code at github,并且有一条评论说 at System.Net.Http.HttpContent.CheckDisposed() at System.Net.Http.HttpContent.CopyToAsync(Stream stream, TransportContext context) at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- end of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at AuditLogsDownload.ConsoleApp.Net.ApiCall.<RetryIfExceptionAsync>d__6.MoveNext() at {filepath}:line 93 用于处理请求的内容但不再是这种情况。我错过了什么?我该如何解决这个错误?事实上,每个类都是C#中的引用类型,这让我不确定如何继续。

1 个答案:

答案 0 :(得分:0)

好的,我已经能够通过断开互联网(在SendAsync()上抛出异常)并运行以下代码来复制问题:

class Program
{
    static void Main(string[] args)
    {
        var client = new HttpClient();
        var content = new StringContent("Hi");
        while (true)
        {
            here:
            var request = new HttpRequestMessage()
            {
                RequestUri = new Uri("https://httpbin.org/post"),
                Method = HttpMethod.Post,
                Content = content
            };
            try
            {
                var response = client.SendAsync(request).Result;
            }
            catch (Exception e)
            {
                goto here;
            }
        }
    }
}

所以基本上HttpClient源代码我看起来“曾经被放弃但不再有的请求”是.NET Core HttpClient的源代码。在.NET框架中(这是我正在使用的)HttpClientSendAsync抛出异常时仍然处理请求。

所以我想解决这个问题的方法是将字符串作为参数传递而不是StringContent,然后在每StringContent之前创建一个新的SendAsync()。相当蹩脚但是我现在能想到的。