I’m trying to simplify a call to a WCF async operation by wrapping the call into a Task on the client side with Task.Factory.FromAsync. But when I Start() the wrapped Task, the call to Start() blocks the client until the debugger reports a ContextSwitchDeadlock. The server side operation gets invoked correctly, though. What am I missing?
WCF contract:
[ServiceContract(Namespace = "urn:test/test")]
public interface ITestContract
{
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginGetResult(AsyncCallback callback, object state);
int EndGetResult(IAsyncResult result);
}
Client code:
var task = Task<int>.Factory.FromAsync(
(callback, state) => service.BeginGetResult(callback, state),
(result) => service.EndGetResult(result)
);
task.Start(); // blocks until ContextSwitchDeadlock gets reported
EDIT: Just for the sake of completeness: No, I can’t use the .NET 4.5 async / await pattern because .NET 4.0 (i.e. Windows XP and Server 2003 support) is a hard requirement for my project.
EDIT2:
The call to Start() should not be necessary anyway. The real problem is that BeginGetResult does not get invoked on the server side until I call Start(), Wait() or Result – which amount to the same thing as a synchronous call.
As I found out, this has nothing to do with Tasks at all. If I do the following, I get the same results:
var asyncResult = service.BeginGetResult(null, null); // BeginGetResult NOT invoked on server side!
asyncResult.AsyncWaitHandle.WaitOne(); // Now BeginGetResult actually gets invoked
EDIT3:
Turns out that it was all just a misunderstanding on my part. I expected that calling BeginGetResult on the client side would immediately call the corresponding BeginGetResult on the server side, i.e. that BeginGetResult on the client side would block until the server actually gets a request, but that does not seem to be the case. Apparently the request is sent in a background thread, so there may be a delay between the client and server side call to BeginGetResult. I suppose this behavior is to be expected, so everthing is fine :-).
You don’t need to call
Starton aTaskcreated byFromAsync.Startis only for tasks with code, and aFromAsynctask does not have any code.