When writing web applications, I often encounter the situation where I would like to start a long process on the server during a post-back and yet return to the client before the process completes. The long process might typically be a lengthy database transaction, creating and sending to an email list, or perhaps some type of report generation.
In a Winform application, I would simply spin a new thread to perform the lengthy operation that would run in the background while my main UI thread would continue. In ASP.NET web applications this gets a bit more complicated than I wish to deal with from within a web page (see below for a threading solution). While it is certainly possible to start a server process to perform the operation, this is also more complex, and I've become very spoiled with the ease of creating web applications with Visual Studio.NET.
Once again, XML Web Services or, as I some times call it, "Poor Man's Remoting" comes to the rescue. The creation of a Web service is so simple with the Framework, especially using Visual Studio.NET, I should not have been surprised that turning a web service into a "fire-and-forget" process was so easy.
For those of you who have not yet created an XML Web Service, you should create a Visual Studio ASP.NET Web Service project. You'll get all of the code for a simple "Hello World" application generated for you. You'll notice that just about the only thing that makes the underlying code-behind different from ASPX web pages, is that each method of the Web service is decorated with the [WebMethod] attribute.
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
When you call a Web service method of this type, the HTTP connection is held open until the WebMethod returns its value to the caller. In the HelloWorld example, the value must be returned, and the processing time is trivial. However, if the WebMethod was a long operation, and there were no return value, it would be desirable to start the method processing and immediately return to the caller in a style similar to a "fire-and-forget" process.
While it's not really fire and forget, the net effect is about the same. By decorating the method with the [SoapDocumentMethod(OneWay=true)] attribute, the server holds the HTTP connection open while it loads and parses the request message, but then returns immediately to the caller with an HTTP 202 response, indicating it has begun processing the request.
[WebMethod]
[SoapDocumentMethod(OneWay=true)]
public void HelloWorld()
{
...run the long process...
}
Voila. I can now include a web service in the form of an ASMX page in my web application that will perform the long operation. By invoking this web service from the post-back server code of my web application, I can return to the client and the process will continue until completion, letting IIS do all of the multitasking/threading work for me.
Threading Solution
For the more adventurous, there is great example on the MSDN site that illustrates a threading solution: How To: Execute a Long-Running Task in a Web Application
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/DIforWC-AP02.asp)
Conclusion
There are, of course, several restrictions. For instance, the web service method must return void, meaning there can be no return value, and no direct way of determining when, and if, the long operation completed. But still, this once again illustrates how the .NET Framework, especially when using Visual Studio.NET, provides solutions that require very little programming to achieve results that in the past would have represented a major development effort.
Note: By default, SOAP messages are in the "document" style of formatting. If you've been using Remote Procedure Call (RPC) formatting for the messages, then you should use [SoapRpcMethod(OneWay=true)], rather than [SoapDocumentMethod(OneWay=true)].
Reference: There is a very good article on this and other web service attributes available at: http://www.zdnet.com.au/builder/dotnet/story/0,2000042147,20270876,00.htm