We have a legacy VB6 application that uses an ASMX webservice written in C# (.NET 4.5), which in turn uses a library (C#/.NET 4.5) to execute some business logic. One of the library methods triggers a long-running database stored procedure at the end of which we need to kick off another process that consumes the data generated by the stored procedure. Because one of the requirements is that control must immediately return to the VB6 client after calling the webservice, the library method is async
, takes an Action
callback as a parameter, the webservice defines the callback as an anonymous method and doesn't await
the results of the library method call.
At a high level it looks like this:
using System; using System.Data.SqlClient; using System.Threading.Tasks; using System.Web.Services; namespace Sample { [WebService(Namespace = "urn:Services")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class MyWebService { [WebMethod] public string Request(string request) { // Step 1: Call the library method to generate data var lib = new MyLibrary(); lib.GenerateDataAsync(() => { // Step 2: Kick off a process that consumes the data created in Step 1 }); return "some kind of response"; } } public class MyLibrary { public async Task GenerateDataAsync(Action onDoneCallback) { try { using (var cmd = new SqlCommand("MyStoredProc", new SqlConnection("my DB connection string"))) { cmd.CommandType = System.Data.CommandType.StoredProcedure; cmd.CommandTimeout = 0; cmd.Connection.Open(); // Asynchronously call the stored procedure. await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); // Invoke the callback if it's provided. if (onDoneCallback != null) onDoneCallback.Invoke(); } } catch (Exception ex) { // Handle errors... } } } }
The above works in local tests, but when the code is deployed as a webservice Step 2 is never executed even though the Step 1 stored procedure completes and generates the data.
Any idea what we are doing wrong?
lib.GenerateDataAsync
(saysGenerateData
which is not shown). I think the issue is that the asmx request has finished executing and "is out the door", and there is "nowhere to execute" the callback. Have you tried awaiting that call? – Mark LarterGenerateDataAsync
runs gets recycled by IIS by the time the call is finished, so there's no context for the callback to execute on. I am just hoping someone who has "been there, done that" can suggest a workaround. – Caspian Canuck