Zajmuję się tworzeniem aplikacji web-api, która pobiera dane z klienta i zapisuje je do późniejszego wykorzystania. Teraz mam system zewnętrzny, który musi znać wszystkie zdarzenia, dlatego chcę skonfigurować komponent powiadomień w moim interfejsie webowym.webapi 2 - jak poprawnie wywołać długotrwałą metodę async/w nowym wątku i zwrócić odpowiedź na klienta
Po zapisaniu danych wykonuję metodę SendNotification(message)
w moim nowym komponencie. Tymczasem nie chcę, aby mój klient czekał, a nawet wiedział, że wysyłamy powiadomienia, więc chcę jak najszybciej zwrócić odpowiedź moim klientom na odpowiedź 201 Created/200 OK
.
Tak, jest to scenariusz polegający na pożarze i zapomnieniu. Chcę, aby komponent powiadomień obsługiwał wszystkie wyjątki (jeśli powiadomienie nie powiedzie się, klient api naprawdę nie przejmuje się wcale).
Próbowałem używać async/await
, ale to nie działa w web-api, ponieważ po zakończeniu wątku żądania, operacja asynchroniczna również to robi.
Więc przyjrzałem się Task.Run()
.
Mój kontroler wygląda tak:
public IHttpActionResult PostData([FromBody] Data data) {
_dataService.saveData(data);
//This could fail, and retry strategy takes time.
Task.Run(() => _notificationHandler.SendNotification(new Message(data)));
return CreatedAtRoute<object>(...);
}
A metoda w moim NotificationHandler
public void SendNotification(Message message) {
//..send stuff to a notification server somewhere, syncronously.
}
Jestem stosunkowo nowy w C# świata, a ja nie wiem, czy istnieje bardziej elegancki (lub właściwy) sposób robienia tego. Czy są jakieś pułapki przy użyciu tej metody?
Dlaczego nie możesz korzystać z asynchronicznych/oczekujących? Ramy powinny się tym zająć. – timothyclifford
Jeśli wykonuję funkcję 'SendNotification()' zwracającą 'asynchroniczne zadanie', muszę' czekać' na wywołanie w mojej klasie kontrolera, a kiedy wrócę do kontrolera, zanim moja metoda asynchroniczna zostanie zakończona, metoda asynchroniczna kończy się, i nigdy się nie kończy. –
To brzmi jak złe zachowanie. Jeśli używasz asynchronizacji, nie powinno to kończyć się przed jej użyciem. Czy możesz dołączyć kod asynchronizowany? – timothyclifford