Подтвердить что ты не робот

Передача * Awaitable * Анонимная функция в качестве параметра

Сначала код. Это то, что я пытаюсь сделать. Я близок, но мне кажется, мне просто нужно исправить то, как я определил свой параметр в методе UpdateButton.

private async void UpdateButton(Action<bool> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}

private void PostToTwitter()
{
    UpdateButton(async () => await new TwitterAction().Post("Hello, world!"));
}

private void PostToFacebook()
{
    UpdateButton(async () => await new FacebookAction().Post("Hello, world!"));
}

К сожалению, !await post() не работает, потому что "Тип" void "не является ожидаемым". Итак, вопрос в том, как определить мой параметр в этом методе для поддержки ожидаемого параметра?

Здесь определяется значение параметра TwitterAction(). Post()...

public virtual async Task<bool> Post(string messageId){...}

4b9b3361

Ответ 1

private async void UpdateButton(Func<Task<bool>> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}

- EDIT -

UpdateButton(()=>Post("ss"));

private async void UpdateButton(Func<Task<bool>> post)
{
    if (!await post())
        this.Text = "Error posting message.";
}

public virtual async Task<bool> Post(string messageId)
{
    return await Task.Factory.StartNew(() => true);
}

Ответ 2

Вам нужно передать это как Task<bool>, а не Action<bool>.

Это обеспечивает что-то "ожидаемое".

Я считаю, что это сработает, учитывая ваш текущий код:

private async Task UpdateButtonAsync(Task<bool> post)
{
    if (!await post)
        ErrorBox.Text = "Error posting message.";
}

// This will work if Post returns Task<bool> in the current API...
private void PostToTwitter()
{
    UpdateButtonAsync(new TwitterAction().Post("Hello, world!"));
}

Если вы не хотите немедленно запускать Task<bool>, и вам нужно сохранить его как прохождение лямбда, все равно нет причины, чтобы лямбда была асинхронной. В этом случае вы можете использовать:

private async Task UpdateButtonAsync(Func<Task<bool>> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}

// This will work if Post returns Task<bool> in the current API...
private void PostToTwitter()
{
    UpdateButtonAsync(() => new TwitterAction().Post("Hello, world!"));
}

Это заставляет лямбда возвращать Task<bool> (нет async/await, как Post уже возвращает Task<bool>), и метод обновления для запуска лямбда.

Лично я считаю, что первый вариант (выше) проще, и подозревайте, что скорее всего вы хотите. Если ваш API уже возвращает Task<T>, вы можете просто передать это и await прямо.