views:

698

answers:

3

Is there a way to tell a WCF service to response to a request (with or without aborting it's processing) after a certain amount of time, even if it didn't finish yet, something like a server-side timeout policy?

+3  A: 

I suppose you could do this by starting a new Thread as soon as the WCF operation starts. The real work then happens on the new thread and the original WCF request thread waits using a Thread.Join() with a specific timeout. If the timeout occurs the worker thread can be canceled using a Thread.Abort().

Something like this:

public string GetData(int value)
{
    string result = "";
    var worker = new Thread((state) =>
    {
        // Simulate l0ng running
        Thread.Sleep(TimeSpan.FromSeconds(value));
        result = string.Format("You entered: {0}", value);
    });

    worker.Start();

    if (!worker.Join(TimeSpan.FromSeconds(5)))
    {
        worker.Abort();
        throw new FaultException("Work took to long.");
    }

    return result;
}
Maurice
thanks, but I don't want to use Thread.Abort on my worker thread, too risky. I'm looking for something that's part of WCF.
Meidan Alon
AFAIK There is no standard WCF option to do this. There is the option to have the client timeout when a request takes to long but the sever is not aware of this and will continue processing the request and will return the result even though no one is listening.BTW The .NET 4.0 Task model makes the treading on the sever somewhat nicer.
Maurice
ended up using such a manual timer, just without aborting the worker.
Meidan Alon
A: 

I don't know why you want to do this - you should probably edit your question to say what you're trying to accomplish.

If I had to do this, then I would have the web service pass the request off to a separate Windows Service, possibly by using WCF over MSMQ. I would have a timeout on that request. If the request didn't finish in time, I'd simply return a Timeout fault. The actual request would not be impacted.

John Saunders
that's exactly what I wanted WCF to do for me, just without the overhead of an extra process.
Meidan Alon
I don't believe it will do this. I've never heard this request before. Maybe you should suggest this as new functionality on Connect (http://connect.microsoft.com/visualstudio/).
John Saunders
A: 

Implement your service using the asynchronous model and have some code monitoring your outstanding requests to see if they've taken too long.

Then, if a timeout occurs before the request can be answered in the real way, then call their callback. The WCF stack provides this when it calls your

BeginFoo( fooParam1, fooParam2, AsyncCallback callback, object state)

Then throw or return your fault/timeout exception or response in the correponding EndFoo() method.

Make sure to not call their callback again if the real answer comes along eventually.

It'll take some getting used to asynchronous wcf programming, but no, apparently there is no server side setting.

Also, you should try to use a client that supports timeout or cancellable requests because you might not be able to rely on the server to time out the request for you. There might not be connectivity or the server machine might have another problem.

Cheers, Chris

Chris Hayworth