简体   繁体   中英

WCF REST Service - Do Work with System.Threading.Tasks.Task

I have a REST WCF Service that allows for the upload and download of information from a webserver. Whilst this works well for very basic actions such as submitting information to the database such as a status update, it doesn't work so well when we make calls to other web services and IO resources which by their nature are longer running tasks.

It's not acceptable for the web service to keep the calling client hanging while it does its work, if for example the client has completed its post of data and we have some number crunching in the background to perform.

My intitial thoughts are that while a client has completed the request we can return an HTTP status of 202 / Accepted and the client can get called back (by other means) once were finished.

Ignoring here for the moment various IO issues in writing to the same path at the same time Async would the below code be a good approach with the use of the WCF service in IIS. I have fears that the running methods could be terminated at any time given an app pool recycle.

public class AsyncService : IAsyncService
{

    public void WriteMessageToDisk(string value)
    {
        Thread.Sleep(120000); // Introduce some arbitrary sleep to keep the client waiting.

        try
        {
            using (var writer = new StreamWriter(AppSettings.StorePath, true))
            {
                writer.WriteLine("{0} - {1}", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss"), value);
            }
        }
        catch (IOException ex)
        {
            WriteMessageToDisk(ex.ToString());
        }
    }

    public void WriteMessageToDiskAsync(string value)
    {
        var task = new Task(() => WriteMessageToDisk(String.Format("Message from Async runner: {0}", value)));

        task.Start();
    }
}

Would this be the best approach to doing some longer running work Asynchronously? I'm also thinking about the possibility of another application to hand these long running requests to so that it doesn't get messy with IIS.

You don't create Task instances directly.

Instead you use the factory and helper method Task.Run

You should also return a Task or Task(TResult) from the asynchronous method.

For instance:

public Task WriteMessageToDiskAsync(string value)
{
    return Task.Run(() => WriteMessageToDisk(String.Format("Message from Async runner: {0}", value)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM