我的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;
}
在服务参考配置中,我选中了“生成异步操作”选项。如何使用生成的GetMessagesAsync()
?在网上我找到了使用AsyncCallback
的例子,但是我并不熟悉。有没有办法以一些友好的方式使用它,如.NET 4.5中的async
和await
关键字?如果没有,我该怎么做才能异步调用该方法?
答案 0 :(得分:7)
如果选择“Generate asynchrounous operations”,您将获得必须使用回调的“旧”行为。
如果要使用新的async / await语法,则必须选择“生成基于任务的操作”(默认选中)。
使用默认Wcf模板时,这将生成以下代理代码:
public System.Threading.Tasks.Task<string> GetDataAsync(int value) {
return base.Channel.GetDataAsync(value);
}
正如您所看到的,没有更多的回调。而是返回Task<T>
。
您可以通过以下方式使用此代理:
public static async Task Foo()
{
using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
{
Task<string> t = client.GetDataAsync(1);
string result = await t;
}
}
您应该使用async
标记调用方法,然后在调用服务方法时使用await
。
答案 1 :(得分:3)
您的服务参考可以(如果您使用.Net 4.5)设置为生成基于任务的异步调用。 (配置服务参考&gt;选中允许生成异步操作&gt;选择生成基于任务的操作)这些可以像任何async
方法一样使用。以下是如何使用它的示例:
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);
}
如果您的客户端未使用.Net 4.5,则无法生成使用async
的服务引用。你必须使用回调的老式方式。这是一个例子:
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);
}
请注意,在这些方案的实际代码中,您不应使用using
或IDisposable.Dispose()
来清理客户端,请参阅Avoiding Problems with the Using Statement和this code以获取你开始陷入困惑的世界,关闭这些事情。
答案 2 :(得分:1)
如果您使用的是VS2012,则可以使用*Async
这样的呼叫:
var proxy = new MyClient();
var result = await proxy.GetMessagesAsync();
答案 3 :(得分:0)
这样的事情怎么样......
public async Task<string> DoSomething()
{
var someProxy = new ServiceClient();
var t = someProxy.SomeMethodAsync();
await Task.WhenAny(t);
return t.Result;
}