Что не так с этим методом async / await? - PullRequest
0 голосов
/ 04 февраля 2019

Я пытаюсь установить свойство источника изображения для Uri, которое возвращается в JSON из API.Возвращенный объект JSON имеет два свойства.

Я создал следующий вспомогательный класс для запроса API и извлечения свойства Uri:

public class GetPicUri
{
    public GetPicUri()
    {
    }

    private string _uri;

    public async Task<string> Get()
    {
        var uri = new Uri("https://randompicture.api/random");
        HttpClient getResponse = new HttpClient();
        var json = await getResponse.GetStringAsync(uri);

        var picture = JsonConvert.DeserializeObject<Picture>(json);

        _uri = picture.Uri;
        return _uri;
    }
}

Это модель, используемая для десериализации JSON:

public class Picture
{
    public Picture()
    {
    }

    public string Description { get; set; }
    public string Uri { get; set; }
}

Проблема в том, что я не могу получить доступ к строковому свойству класса GetPicUri:

var picUri = new GetPicUri();
string imageSource = picUri.Get();

Когда я пытаюсь это сделать, я каждый раз получаю исключение:

не может преобразовать из 'System.Threading.Tasks.Task' в 'string'

Я пробовал нарезать целую кучу разных способов, например, используя Uri какстатическая строка и имеющая метод Get как async Task (или void), и она просто обновляет статическую строку и вызывается из конструктора.Я попытался запустить его как метод Get для свойства.Но я не могу заставить его работать.

Так что я думаю, у меня есть два вопроса, первый из которых заключается в том, что я делаю не так здесь конкретно, и с точки зрения дизайна, какой будет правильный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

ваш метод get возвращает задачу (в основном объект содержит информацию о задаче, такую ​​как состояние и т. Д.), Любой асинхронный метод должен возвращать задачу (или аннулировать), вам нужно асинхронно ждать завершения этой задачи, используя ключевое слово await

string imageSource = await picUri.Get();

с использованием вышеуказанного подхода вам придется изменить вызывающий метод также на асинхронный, и вы найдете ключевое слово async, распространяющееся в коде вашего кода

, или заставите метод вести себя синхронно, получивсвойство Result из объекта задачи, возвращенного методом get (что делает его бесполезным для объявления метода Get асинхронным)

string imageSource = picUri.Get().Result;
0 голосов
/ 04 февраля 2019

Хорошей практикой является добавление Aync к имени метода, если он фактически асинхронный - например:

public async Task<string> GetAsync()
{
    var uri = new Uri("https://randompicture.api/random");
    HttpClient getResponse = new HttpClient();
    var json = await getResponse.GetStringAsync(uri);

    var picture = JsonConvert.DeserializeObject<Picture>(json);

    _uri = picture.Uri;
    return _uri;
}

вызов с использованием:

await picUri.GetAsync();
...