将重写的成员更改为异步

Jer*_*ser 14 c# async-await

我正在覆盖基类库中的方法.但是,在我重写的实现中,我正在使用全新的HttpClient,它全部基于异步方法.因此我必须将我的方法标记为异步,这意味着我需要将方法的返回参数从字符串更改为任务.然而,编译器给出了一个错误:"返回类型必须是'string'才能匹配被覆盖的成员...."

    public class BaseClass
    {
        public virtual string GetName()
        {
            ...
        }
    }

    public class MyClass : BaseClass
    {
        public override async Task<string> GetName()
        {
            HttpClient httpClient = new HttpClient();
            var response = await httpClient.GetAsync("");
            if (response.IsSuccessStatusCode)
            {
                var responseContent = response.Content;

                return await responseContent.ReadAsStringAsync();
            }

            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

当然,显而易见的解决方案是将BaseClass中的GetName()的返回类型更改为Task <string>,但我无法控制BaseClass,因为它是一个外部库;

我目前的解决方案是以同步方式使用HttpClient类,即更改MyClass,如下所示:

    public class MyClass : BaseClass
    {
        public override string GetName()
        {
            HttpClient httpClient = new HttpClient();
            var response = httpClient.GetAsync("");
            if (response.Result.IsSuccessStatusCode)
            {
                var responseContent = response.Result.Content;

                return responseContent.ReadAsStringAsync()
                                                       .Result;
            }

            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以做到这一点?

Jar*_*Par 10

不幸的是,这里没有一个好的解决方案.使用override异步方法无法使用非异步方法.我认为你最好的选择是使用async非重写方法并从非异步方法调用它:

public class MyClass : BaseClass 
{
    public override string GetName() 
    {
        return GetNameAsync().Value;
    }

    public async Task<string> GetNameAsync() 
    { 
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这可能会导致问题.如果原始代码没有期望任何async代码执行,那么引入这种模式可能会打破期望.如果可能的话我会避免它.

  • 难道这个解决方案不是等待发生的僵局吗? (4认同)