我正在学习async/await,并遇到了需要同步调用异步方法的情况.我怎样才能做到这一点?
异步方法:
public async Task<Customers> GetCustomers()
{
return await Service.GetCustomersAsync();
}
Run Code Online (Sandbox Code Playgroud)
正常使用:
public async void GetCustomers()
{
customerList = await GetCustomers();
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用以下内容:
Task<Customer> task = GetCustomers();
task.Wait()
Task<Customer> task = GetCustomers();
task.RunSynchronously();
Task<Customer> task = GetCustomers();
while(task.Status != TaskStatus.RanToCompletion)
Run Code Online (Sandbox Code Playgroud)
我也从这里尝试了一个建议,但是当调度程序处于暂停状态时它不起作用.
public static void WaitWithPumping(this Task task)
{
if (task == null) throw new ArgumentNullException(“task”);
var nestedFrame = new DispatcherFrame();
task.ContinueWith(_ => nestedFrame.Continue = false);
Dispatcher.PushFrame(nestedFrame);
task.Wait();
}
Run Code Online (Sandbox Code Playgroud)
以下是调用的异常和堆栈跟踪RunSynchronously:
System.InvalidOperationException
消息:可能无法在未绑定到委托的任务上调用RunSynchronously.
InnerException:null
资料来源:mscorlib …
我可能在这里遗漏了一些明显的东西.
我正在使用Message字符串中包含的HttpClient哪个throws .HttpRequestExceptionStatusCode
我该如何访问StatusCode?
编辑:更多信息,我急着写这个问题.
我正在使用HttpClient我的WebApi项目中的另一个API.是的,我知道我为什么打电话EnsureSuccessStatusCode().我想在下游传播一些错误,例如404和403.
我想要的只是不断变换HttpRequestException为HttpResponseException使用自定义ExceptionFilterAttribute.
不幸的是,HttpRequestException除了消息之外,我没有携带任何额外的信息.我希望以StatusCode原始(int或enum)形式发现.
看起来我可以:
我使用下面的代码向服务器发送POST请求:
string url = "http://myserver/method?param1=1¶m2=2"
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request);
Run Code Online (Sandbox Code Playgroud)
我没有访问服务器进行调试,但我想知道,这个请求是以POST还是GET发送的?
如果是GET,如何更改我的代码以将param1和param2作为POST数据发送(不在URL中)?
我正在调用我的Web API HttpClient,我看到有一个EnsureSuccessStatusCode方法和一个IsSuccessStatusCode属性.哪一个合适?
我读了这篇文章,还有一些问题:
使用EnsureSuccessStatusCode并处理它抛出的HttpRequestException
我遇到的问题是,如果我发送一个GET请求,我传递了ID我想要检索的对象,基本上有两个结果:
如果我调用EnsureSuccessStatusCode()状态404将导致抛出异常.这并不理想,因为当我测试我的代码时,我一直收到404错误,这首先让我觉得API URL不正确,但实际上没有匹配的对象与提供的Id.在这种情况下,我宁愿返回一个null对象而不是抛出异常.
所以我尝试检查IsSuccessfulStatusCode属性的值.这似乎是一个更好的选择,当此属性为false时,我可以返回一个null对象,但是,有许多状态代码可能导致此属性具有false值.404是其中之一,但还有其他几个状态代码,例如400 Bad Request,405 Method Not Allowed等.我想记录除404之外的所有不成功的错误代码的异常,我想知道是否有一种更好的方法可以做到这一点,而不是检查ResponseCode响应的值,然后抛出一个由我的catch块捕获的异常,这是记录发生的地方.
这是我的GET方法的代码:
public static Customer GetCustomerByID(int id)
{
try
{
using (var client = GetConfiguredClient())
{
Customer customer = null;
var requestUri = $"Customers/{id}";
using (var response = client.GetAsync(requestUri).Result)
{
if (response.IsSuccessStatusCode)
customer = response.Content.ReadAsAsync<Customer>().Result;
}
return customer;
}
}
catch (Exception ex)
{
ex.Data.Add(nameof(id), id);
LogException(ex);
throw; …Run Code Online (Sandbox Code Playgroud) 在我的场景中,我必须将数据从一个 Web 应用程序发送到一个有效的数据存储 webapi。请求必须是同步的,Exception如果出现问题,我绝对希望抛出,因为这意味着应用程序的关键部分不可用。
这是现有问题的衍生,但不是重复;为什么使用 HttpClient 进行同步连接。
然而一遍又一遍,包括在我上面看到的文章中,我看到一致的建议使用HttpClient,即使在同步场景中也是如此。我看到的最好的原因是上面 SO 帖子中接受的答案,但它基本上归结为;
使用它是因为“闪亮”。
对于我的场景,我不喜欢这是一个可接受的答案。我更愿意为手头的任务使用正确的对象,这似乎是较旧的HttpWebRequest. 甚至 Ben Watson 的优秀资源“编写高性能 .NET 代码”也说明了以下内容;
另一个例子是
System.Net.HttpWebRequest类,如果它收到来自服务器的非 200 响应,它将抛出异常。幸运的是,这种奇怪的行为System.Net.Http.HttpClient在 .NET 4.5的类中得到了纠正
但在我的情况,我其实不希望这样的行为。虽然 有很多很好的用例HttpClient,但谁能提供一个不在HttpWebRequest我的场景中使用的好理由?我是否使用了正确的对象?更重要的是,为什么?
c# ×5
httpclient ×2
async-await ×1
asynchronous ×1
c#-5.0 ×1
httpresponse ×1
parameters ×1
post ×1