Ожидать в рамках метода огня и забыть - PullRequest
0 голосов
/ 25 мая 2018

Я заметил, что когда await находится в методе, который я запускаю, и забыл, что приложение сделает его только до await, тогда оно будет действовать, как если бы оно достигло return.В упрощенной версии того, что я сейчас смотрю, у вас может быть:

public void DoTheThing() {
    ...
    Task fireAndForget = SendAsync(emails);
}

public async Task SendAsync(List<Email> emails) {
    foreach (var email in emails) {
        var to = email.to;
        var body = email.body;
        await EmailSenderAsync(to,body);
        await Task.Delay(3000);
    }
}

Это никогда не пройдет через строку await EmailSenderAsync(to,body);, и будет отправлено только самое первое письмо в emails.EmailSenderAsync - это внешний код, поэтому я не могу войти в него.Добавление await к SendAsync(emails) заставит все работать нормально ... но тогда это не огонь и забудь.

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

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

У меня была похожая проблема на днях.Я объявил мои await методы в качестве задач, а затем передал их Task.WhenAll.

Попробуйте:

var taskEmailSendAsync = EmailSenderAsync(to, body);
var taskDelay = Task.Delay(3000);

await Task.WhenAll(taskEmailSenderAsync, taskDelay)
0 голосов
/ 25 мая 2018

Как упоминал Камило, элемент управления возвращается вашему родителю.Убедитесь, что ваш родитель все еще там с чем-то вроде этого:

var parentContext = Task.Run(() => DoTheThing() );
parentContext .Wait();
...