How to use Visual Studio - generated async WCF calls?
Solution 1
If you select 'Generate asynchrounous operations', you will get the 'old' behavior where you have to use callbacks.
If you want to use the new async/await syntax, you will have to select 'Generate task-based operations' (which is selected by default).
When using the default Wcf template, this will generate the following proxy code:
public System.Threading.Tasks.Task<string> GetDataAsync(int value) {
return base.Channel.GetDataAsync(value);
}
As you can see, there are no more callbacks. Instead a Task<T>
is returned.
You can use this proxy in the following way:
public static async Task Foo()
{
using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
{
Task<string> t = client.GetDataAsync(1);
string result = await t;
}
}
You should mark the calling method with async
and then use await
when calling your service method.
Solution 2
Your Service Reference can (if you are using .Net 4.5) be set to generate task-based async calls. (Configure Service Reference > check Allow generation of asynchronous operations > select Generate task-based operations) These can be used like any async
method. Here's an example of how to use it:
using (var proxy = new YourServiceClient())
{
var t1 = proxy.GetMessagesAsync();
var t2 = proxy.GetMessagesAsync();
//they're runnning asynchronously now!
//let's wait for the results:
Task.WaitAll(t1, t2);
var result1 = t1.Result;
var result2 = t2.Result;
Console.WriteLine(result1);
Console.WriteLine(result2);
}
If your client is not using .Net 4.5, you cannot generate service references that use async
. You'll have to do it the old fashioned way, using callbacks. Here's an example:
static void m()
{
var proxy = new YourServiceClient();
proxy.GetMessagesCompleted += proxy_GetMessagesCompleted;
proxy.GetMessagesAsync();
}
static void proxy_GetMessagesCompleted(object sender, GetMessagesCompletedEventArgs e)
{
var proxy = (IDisposable)sender;
proxy.Dispose(); //actual code to close properly is more complex
if (e.Error != null)
{
// do something about this
}
var result = e.Result;
Console.WriteLine(result);
}
Note that in actual code for either of these scenarios, you shouldn't use using
or IDisposable.Dispose()
to clean up the client, see Avoiding Problems with the Using Statement and this code to get you started into the confusing world of closing these things.
Solution 3
If you're on VS2012, then you can use the *Async
calls like this:
var proxy = new MyClient();
var result = await proxy.GetMessagesAsync();
Comments
-
pmichna almost 2 years
My
OperationContract
:public List<MessageDTO> GetMessages() { List<MessageDTO> messages = new List<MessageDTO>(); foreach (Message m in _context.Messages.ToList()) { messages.Add(new MessageDTO() { MessageID = m.MessageID, Content = m.Content, Date = m.Date, HasAttachments = m.HasAttachments, MailingListID = (int)m.MailingListID, SenderID = (int)m.SenderID, Subject = m.Subject }); } return messages; }
In Service Reference configuration I checked the option "Generate asynchronous operations". How do I use the generated
GetMessagesAsync()
? In the net I found examples that useAsyncCallback
, however I'm not familiar with that. Is there a way to use it in some friendly way likeasync
andawait
keywords in .NET 4.5? If not, what should I do to invoke the method asynchronously?