客户
iGame Channel = new ChannelFactory<iGame> ( new BasicHttpBinding ( BasicHttpSecurityMode . None ) , new EndpointAddress ( new Uri ( "http://localhost:58597/Game.svc" ) ) ) . CreateChannel ( );
public Task<SerializableDynamicObject> Client ( SerializableDynamicObject Packet )
{
return Task<SerializableDynamicObject> . Factory . FromAsync ( Channel . BeginConnection , Channel . EndConnection , Packet , null );
}
合同
[OperationContract ( AsyncPattern = true )]
IAsyncResult BeginConnection ( SerializableDynamicObject Message , AsyncCallback Callback , object State );
SerializableDynamicObject EndConnection ( IAsyncResult Result );
服务
public IAsyncResult BeginConnection ( SerializableDynamicObject Message , AsyncCallback Callback , object State )
{
dynamic Request = Message;
dynamic Response = new SerializableDynamicObject ( );
if ( Request . Operation = "test" )
{
Response . Status = true;
}
Response . Status = false;
return new CompletedAsyncResult<SerializableDynamicObject> ( Response );
}
public SerializableDynamicObject EndConnection ( IAsyncResult Result )
{
return ( Result as CompletedAsyncResult<SerializableDynamicObject> ) . Data;
}
从Silverlight客户端公开服务
private async void myButton ( object sender , RoutedEventArgs e )
{
dynamic Request = new SerializableDynamicObject ( );
Request . Operation = "test";
var task = Client ( Request );
var result = await task; // <------------------------------ Exception
}
例外
Task<SerializableDynamicObject > does not contain a definition for 'GetAwaiter'
怎么了 ?
编辑1:
简单地说,
Visual Studio 2012 RC Silverlight 5应用程序使用ASP.net中托管的游戏WCF 4服务4通过共享可移植库.NET4 / SL5使用ChannelFactory技术的应用程序包含带有Async CTP的iGame界面
图表: ASP.NET <=类库(游戏)<=可移植库(iGame)=> Silverlight
编辑2:
由GetAwaiter()
使用的await
在Async CTP中实现为扩展方法。我不确定你到底在用什么(在你的问题中你提到了Async CTP和VS 2012 RC),但异步定位包可能使用相同的技术。
那么问题是扩展方法不适用于dynamic
。您可以做的是明确指定您正在使用Task
,这意味着扩展方法将起作用,然后切换回dynamic
:
private async void MyButtonClick(object sender, RoutedEventArgs e)
{
dynamic request = new SerializableDynamicObject();
request.Operation = "test";
Task<SerializableDynamicObject> task = Client(request);
dynamic result = await task;
// use result here
}
或者,因为Client()
方法实际上不是动态的,你可以用SerializableDynamicObject
而不是dynamic
来调用它,所以尽可能使用dynamic
进行限制:
private async void MyButtonClick(object sender, RoutedEventArgs e)
{
var request = new SerializableDynamicObject();
dynamic dynamicRequest = request;
dynamicRequest.Operation = "test";
var task = Client(request);
dynamic result = await task;
// use result here
}
我在我的一个项目中遇到过这个问题,我发现我已将项目.net
版本设置为4.0,并且仅在病房中的.net
4.5中支持异步任务。
我只是将我的项目设置更改为使用.net
4.5或更高版本并且它有效。
您必须安装Microsoft.Bcl.Async NuGet包才能在.NET 4.5之前的版本中使用async/await
构造(例如Silverlight 4.0+)
为了清楚起见 - 这个包曾经被称为Microsoft.CompilerServices.AsyncTargetingPack
,一些旧的tutorials仍然提到它。
快来看看here来自Immo Landwerth的信息。
刚刚在执行linq查询的方法中体验过这一点。
public async Task<Foo> GetSomething()
{
return await (from foo in Foos
select foo).FirstOrDefault();
}
需要使用.FirstOrDefaultAsync()
代替。 N00b错了。
您仍然可以使用框架4.0,但您必须为类包含getawaiter
:
MethodName(parameters).ConfigureAwait(false).GetAwaiter().GetResult();
确保您的.NET 4.5或更高版本
我有这个问题,因为我正在调用一个方法
await myClass.myStaticMethod(myString);
但我正在设置myString
var myString = String.Format({some dynamic-type values})
导致dynamic
类型,而不是string
,因此当我试图等待myClass.myStaticMethod(myString)
时,编译器认为我打算调用myClass.myStaticMethod(dynamic myString)
。这个编译得很好,因为再次,在动态上下文中,它一切都很好,直到它在运行时爆炸,这是因为没有动态版本的myStaticMethod
的实现,并且这个错误消息没有任何帮助,而Intellisense将我带到正确定义的事实也无济于事。
整蛊!
但是,通过将结果类型强制为字符串,例如:
var myString = String.Format({some dynamic-type values})
至
string myString = String.Format({some dynamic-type values})
我对myStaticMethod
的呼吁正确排除
在我的情况下,只需添加using System;
解决问题。
public async Task<model> GetSomething(int id)
{
return await context.model.FindAsync(id);
}