C# http请求在嵌套异步任务中不起作用<;T>;方法

C# http请求在嵌套异步任务中不起作用<;T>;方法,c#,.net,asynchronous,httprequest,C#,.net,Asynchronous,Httprequest,我第一次使用异步任务,遇到了一个似乎无法解决的问题 我有一个使用Http请求调用API的方法 internal static async Task<HttpResponse> CallAPI(string objectname, string parameters, HttpMethod method) { HttpResponse r = new HttpResponse(); using (r.HttpClient = new HttpC

我第一次使用异步任务,遇到了一个似乎无法解决的问题

我有一个使用Http请求调用API的方法

internal static async Task<HttpResponse> CallAPI(string objectname, string parameters, HttpMethod method)
    {
        HttpResponse r = new HttpResponse();

        using (r.HttpClient = new HttpClient())
        {
            r.HttpClient.BaseAddress = new Uri("https://" + Properties.Settings.Default.APIURL + "/");
            r.HttpClient.DefaultRequestHeaders.Clear();
            r.HttpClient.DefaultRequestHeaders.Add("Accept", "application/vnd+json;version=1");

            r.HttpClient.DefaultRequestHeaders.Add("Host", Properties.Settings.Default.APIURL);
            r.HttpClient.DefaultRequestHeaders.Add("Expect", "100-continue");
            r.HttpClient.DefaultRequestHeaders.Add("Connection", "Close");

            switch (method)
            {
                case HttpMethod.DELETE:
                    using (r.ResponseMessage = await r.HttpClient.DeleteAsync("api/" + objectname.ToString() + "/" + parameters))
                    {
                        var stopwatch = Stopwatch.StartNew();
                        r.responseTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
                        r.ResponseData = await r.ResponseMessage.Content.ReadAsStringAsync();
                        return r;
                    }

                case HttpMethod.GET:
                    using (r.ResponseMessage = await r.HttpClient.GetAsync("api/" + objectname.ToString() + parameters))
                    {
                        var stopwatch = Stopwatch.StartNew();
                        r.responseTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
                        r.ResponseData = await r.ResponseMessage.Content.ReadAsStringAsync();
                        return r;
                    }
                default: throw new Exception("No HTTP Method Found");
            }
        }
但如果我试图将Delete()作为一项任务

公共异步虚拟任务删除() { 尝试 { HttpResponse r=新的HttpResponse(); r=wait CallAPI(_Objectname.ToString(),_Id.ToString(),HttpMethod.DELETE); 返回true; } 抓住 { 返回false; } } 它尝试执行httpclient.deleteasync方法,但应用程序什么也不做。我没有任何例外,它不会冻结,只是看起来不再有任何作用


我不知道是什么导致了这种行为,但我对异步编程相当陌生,所以我可能正在做一些我不应该做的事情:-)

如果你做了
.Result
.Wait()
在使用async/Wait的代码上,你必须使你的事件处理程序
async void
,这是唯一允许您使用
async void
的地方

protected async void btnDelete_Click(object sender, EventArgs e)
{
    Activity a = new Activity();
    a.Id = Convert.ToInt32(txtObjectId.text);
    //await a.Delete(); //Task method
    bool done = await a.Delete(); //Task<bool> method
}
您不需要
return
语句

此外,如果不需要访问UI,请将
.ConfigurateAwait(false)
添加到每个等待调用,以使其不强制UI线程继续

public async virtual Task Delete()
{
        HttpResponse r = new HttpResponse();
        r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE).ConfigureAwait(false);                         
}

您也可以对
CallAPI
执行相同的操作,以使其更好地运行。

如何调用
Delete()
?我敢打赌,您正在死锁自己,这就是
异步void
工作的原因。(顺便说一句,除非您正在编写一个将成为事件处理程序的函数)delete方法是类对象的一部分<代码>活动a=新活动();a、 id=12345;a、 删除()和活动从基类继承
delete()
,因此您只需调用
a.delete()
,而不调用
Wait a.delete()
a.delete().Result
a.delete().Wait()
?另外,您的代码没有继承,您正在执行
public async virtual Task Delete()
,如果它是从基类继承的,那么它将是
public async override Task Delete()
不,我确实调用
wait a.Delete()
对不起,我以为您说的是“我不调用
wait a.Delete()
”。您需要更新您的问题,您遇到的问题不在您向我们展示的代码中。您需要显示整个调用堆栈链,直到找到框架代码。如果链中的任何位置都有
.Result
.Wait()
,则会导致此问题。
     public async virtual Task<bool> Delete()
    {
        try
        {
            HttpResponse r = new HttpResponse();
            r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE);                
            return true;
        }
        catch
        {
            return false;
        }
    }
protected async void btnDelete_Click(object sender, EventArgs e)
{
    Activity a = new Activity();
    a.Id = Convert.ToInt32(txtObjectId.text);
    //await a.Delete(); //Task method
    bool done = await a.Delete(); //Task<bool> method
}
public async virtual Task Delete()
{
        HttpResponse r = new HttpResponse();
        r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE);                         
}
public async virtual Task Delete()
{
        HttpResponse r = new HttpResponse();
        r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE).ConfigureAwait(false);                         
}