クライアント
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アプリケーション消費ゲームWCF 4サービスホストASP.net 4アプリケーション ChannelFactoryテクニックを共有経由で使用Portable Library .NET4/SL5には、iGameインターフェイスが含まれます- 非同期CTP
グラフ:
ASP.NET <=クラスライブラリ(ゲーム)<=ポータブルライブラリ(iGame)=> Silverlight
編集2:
await
で使用されるGetAwaiter()
は、非同期CTPの拡張メソッドとして実装されます。正確に何を使用しているのかわかりません(質問でAsync CTPとVS 2012 RCの両方に言及しています)が、Asyncターゲティングパックが同じ手法を使用している可能性があります。
問題は、拡張メソッドが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
}
_
私のプロジェクトの1つでこの問題がありました。プロジェクトの.net
バージョンを4.0に設定し、非同期タスクは病棟の.net
4.5でのみサポートされています。
プロジェクトの設定を変更して.net
4.5以上を使用するだけで機能しました。
.NET 4.5より前のバージョン(Silverlight 4.0+など)でasync/await
コンストラクトを使用するには、 Microsoft.Bcl.Async NuGetパッケージをインストールする必要があります
わかりやすくするために-このパッケージはMicrosoft.CompilerServices.AsyncTargetingPack
と呼ばれ、古い tutorials と呼ばれています。
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以降を確認してください
私の場合は、using System;
問題を解決します。
メソッドを呼び出していたため、この問題が発生しました
_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
への呼び出しが適切にルーティングされました
public async Task<model> GetSomething(int id)
{
return await context.model.FindAsync(id);
}