【问题标题】:Asynchronous Task results in exception: System.ArgumentException: An item with the same key has already been added异步任务导致异常:System.ArgumentException:已添加具有相同键的项
【发布时间】:2017-05-08 23:40:54
【问题描述】:

异步执行 REST 调用和处理响应。

System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Net.Http.Headers.HttpHeaders.AddHeaderToStore(String name, HeaderStoreItemInfo info)
   at System.Net.Http.Headers.HttpHeaders.CreateAndAddHeaderToStore(String name)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(String name, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaders.SetParsedValue(String name, Object value)
   at System.Net.Http.Headers.HttpContentHeaders.get_ContentLength()
   at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()

代码:

var resultTask = base.WrapCallWithLogging(requestUri, task, method, sw, content);

resultTask.ContinueWith(t =>
{
    // Do something 
    GetMessage(); //access the variable content
};

return resultTask;

我的理解是我们得到了这个异常,因为出于某种原因,标题被创建了两次。这可能是异步任务的问题。谁能指出正确的文档?

base.WrapCallWithLogging()方法:

protected virtual Task<HttpResponseMessage> WrapCallWithLogging(RestUri requestUri, Task<HttpResponseMessage> task, HttpMethod method, Stopwatch sw, HttpContent content = null)
{
    var uriTemplate = requestUri.BuildFullTemplateString();
    Logger.DebugFormat("Making http '{0}' call to '{1}'", method, uriTemplate);
    return task.ContinueWith(r =>
    {
        var result = r.Result;
        sw.Stop();
        Logger.DebugFormat("Ending http '{0}' call to '{1}' with status code {2} in {3} ms",
           method, 
           uriTemplate.ToString(),
           result == null ? HttpStatusCode.InternalServerError : result.StatusCode,
           sw.ElapsedMilliseconds);

        return result;
    });
}

【问题讨论】:

  • WrapCallWithLogging() 显然有一些问题。显示它的代码。
  • abatishchev 添加了基本方法
  • 嗯,有趣/奇怪。您是否在任何地方手动操作 http 客户端的标头?
  • 你在使用 RestSharp 吗?能更新到最新吗?您可以尝试使用内置的 HttpClient 代替吗?
  • 这不是一个解决方案,但也尝试使用async/await 而不是普通的TPL ContinueWith()

标签: c# task-parallel-library


【解决方案1】:

异常堆栈跟踪将您带到以下代码行:

var result = r.Result;

r 这是第一个片段中的task

var resultTask = base.WrapCallWithLogging(requestUri, task, method, sw, content);

所以,就你没有提供它的初始化而言,很难说它有什么问题,但你应该调查它的代码。你说的错误信息是

异步任务导致异常:System.ArgumentException: 已添加具有相同键的项

可以在此处找到具有解决方案的类似错误:

An item with the same key has already been added

很可能,您的模型包含两次相同的属性。也许您正在使用 new 来隐藏基本属性。
解决方案是覆盖该属性或使用其他名称。
如果您分享您的模型,我们将能够详细说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2017-04-15
    • 2014-12-18
    • 1970-01-01
    相关资源
    最近更新 更多