Fire-forget and One-Way Calls in ASP.NET WebApi
Asked Answered
G

2

5

I totally understand that HTTP world is not the best choice for one-way calls and that WebApi is designed best for HTTP verbose communications. No doubt, WCF is the winner here. But, what if you already have an ApiController with a bunch of verbs exposed and at some point you needed to have a single one-way call too? And you don't want to host/maintain another service (WCF) for that.

Task<HttpResponseMessage> response = client.PostAsJsonAsync<Log>("api/log", log)

If you don't handle the response then you've got something similar to fire-and-forget. Is this the only way in WebApi or there's another solution?

Germanous answered 18/12, 2012 at 16:33 Comment(1)
I hope you'd share the outcome and pick, or add an answer. It'd be helpful to others.Amorino
P
6

Why not just call like this and ignore the returned task?

client.PostAsJsonAsync<Log>("api/log", log);

I do this with all my calls and use a handler in the response pipeline to deal with responses if necessary.

Pussyfoot answered 18/12, 2012 at 19:21 Comment(3)
This code is potentially dangerous because of unobserved task exceptions.Rad
In fire-and-forget environment only communication exceptions should be handled on the client. The calling thread will fail with a thrown exception anyway, in case of communication problems. The rest is the headache of the service itself, so unobserved task exceptions should not be dangerous here.Germanous
@Darrel do you define your WebApi verbs as void or Task for one-way calls? For this particular issue I think void should be preferred since you're not imply any await-ness/await-ability for O/W operations.Germanous
R
5

Your best bet is to start a new Task and send the response immediately rather than returning the task:

public void PostDoFireAndForget() // and NOT public Task PostDoFireAndForget()
    {
        Task.Factory.StartNew
            (() =>
                {
                    // ... start the operation here
                    // make sure you have an exception handler!!
                }

            );

    }
Rad answered 18/12, 2012 at 17:39 Comment(7)
The only problem I see with this is that if the calling method ends before the actual remote call gets executed the call may never happen since the thread was killed together with the main thread. You should consider that when adopting this solution.Euphonious
Well that is the inherent problem with fire and forget on a request-response protocol. But chance is really slimRad
@DarrelMiller because returning a Task mean the response will not be returned until task is finished which is not the same as what OP wants.Rad
@Rad Any call to XXXAsync should return very quickly. The OP wants to do FireAndForget which I interpret to mean, he doesn't care about a response.Pussyfoot
@DarrelMiller if you are NOT returning a task then it is fine. But your code is dangerous since you are not observing the task exceptions.Rad
@Rad I guess the inherent problem with fire and forget on a request-response protocol you mention has nothing to do with the return type of the WebApi methood, right? And I agree with the void, but without starting a new task.Germanous
See #1019110Herald

© 2022 - 2024 — McMap. All rights reserved.