I have a recent experience I\'d like to share that may be helpful to anyone having to maintain a legacy ASMX web service that must be updated to call Task-based methods.
Upon further investigation, I discovered that sub-tasks created by the initial task could be awaited without any problems, but the parent task (i.e. the method call in the ASMX that returned a Task
The investigation led me to theorise that there was some sort of incompatibility between the legacy Web Services stack and the Task Parallel Library. The solution that I came up with involves creating a new thread to run the Task-based method calls, the idea being that a separate thread would not be subject to thread/task management incompatibilities that existed in the thread processing the ASMX request. To this end I created a simple helper class that will run a Func
public class ThreadRunner {
// The function result
private T result;
//The function to run.
private readonly Func function;
// Sync lock.
private readonly object _lock = new object();
// Creates a new ThreadRunner.
public ThreadRunner(Func function) {
if (function == null) {
throw new ArgumentException("Function cannot be null.", "function");
}
this.function = function;
}
// Runs the ThreadRunner's function on a new thread and returns the result.
public T Run() {
lock (_lock) {
var thread = new Thread(() => {
result = function();
});
thread.Start();
thread.Join();
return result;
}
}
}
// Example:
//
// Task MyTaskBasedMethod() { ... }
//
// ...
//
// var tr = new ThreadRunner(() => MyTaskBasedMethod().Result);
// return tr.Run();
Running the Task-based method in this way works perfectly and allows the ASMX call to complete successfully, but it's obviously a bit brute-force to spawn a new thread for every asynchronous call; alternatives, improvements or suggestions are welcome!