这是我得到的错误:
One or more errors occurred.
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()
at myProject.mymethod(Int32[] myIds) in path\MyClass.cs:line 758
Run Code Online (Sandbox Code Playgroud)
这是方法:
private void mymethod(int[] myIds)
{
var uri = new Uri(string.Format(UriPath, string.Format(MyPath)));
var client = GetHttpClient(uri);
var postModel = new PostModel
{
Ids = myIds,
LastUpdate = NewItem ? null : _lastUpdated
};
if (client != null)
{
var response = client.PostAsJsonAsync(uri, postModel).Result;//this line crashes
if (response.IsSuccessStatusCode)
{
//doSomething
}
}
}
Run Code Online (Sandbox Code Playgroud)
我调用了很多这样的方法,除了这个之外它们都有效.当它被击中时,需要花费很多时间,然后抛出这个异常.使用所有其他方法时,错误不会发生.
这是内在的例外:
Inner.System.Threading.Tasks.TaskCanceledException: A task was canceled.
Run Code Online (Sandbox Code Playgroud)
这是我的GetCLient()方法:
private HttpClient GetHttpClient(Uri uri)
{
var handler = new HttpClientHandler
{
CookieContainer = CoockieContainer
};
return new HttpClient(handler)
{
BaseAddress = uri
};
}
Run Code Online (Sandbox Code Playgroud)
这是API方法:
[HttpPost]
public IList<MyModel> MyAPIMethod(PostModel model)
{
List<MyModel> myTranslations;
using (var db = new myEntities(GetDbConnStrByUser(new GetCookies().GetUserName())))
{
myTranslations = db.tblTranslations.Where(it => model.Ids.Contains(it.id)
&& (!model.Update.HasValue || it.update > model.LastUpdate.Value))
.Select(it => new MyModel
{
Id = it.id,
Name = it.name,
Description = it.desc,
LanguageId = it.language_id
}).ToList();
}
return myTranslations.GroupBy(x => new { x.Id, x.LanguageId }).Select(x => x.First()).ToList();
}
Run Code Online (Sandbox Code Playgroud)
可能发生超时.
Fiddler返回此错误:等待操作超时.
sco*_*732 13
.Result尝试将Task变为T.它同步阻止等待任务完成,并且只有在没有异常发生时才返回T. 您应该预期的两种类型的异常是OperationCanceledExceptions/TaskCanceledExceptions(当HTTP请求超时或使用CancellationToken且令牌被取消时 - 我不认为后者适用于此处)和一般/ HTTP相关的异常.
您可能正在遇到HTTP超时方案.是否需要很长时间才能抛出异常?如果没有,你的GetHttpClient
方法是什么样的?是明确设置超时还是取消令牌?
如果你想坚持使用同步方法而不返回任务,你应该做这样的事情:
try
{
var response = client.PostAsJsonAsync(uri, postModel).Result;//this line crashes
}
catch (OperationCanceledException oce)
{
// Tell the user that the request timed our or you cancelled a CancellationToken
}
catch (Exception exc)
{
// Look at the HttpClient docs and try to catch something more specific. You don't want
// to swallow StackOverflowExceptions or OutOfMemoryExceptions.
}
Run Code Online (Sandbox Code Playgroud)
如果你愿意接受异步暴跌,那么这就是你想要的更多:
private async Task mymethodAsync(int[] myIds)
{
var uri = new Uri(string.Format(UriPath, string.Format(MyPath)));
var client = GetHttpClient(uri);
var postModel = new PostModel { ... };
if (client != null)
{
try
{
var response = await client.PostAsJsonAsync(uri, postModel);
if (response.IsSuccessStatusCode)
{
//doSomething
}
}
catch (OperationCanceledException oce)
{
// because timeouts are still possible
}
catch (Exception exc) {
// Because other things can still go wrong too (HTTP 500, parsing errors)
}
}
}
Run Code Online (Sandbox Code Playgroud)
有关.Result调用如何使用HttpClient的更多信息,请参阅此处:在等待任务结果时会发生什么?