クライアントのサンプルコードでは非同期操作を待った後、いずれかの操作でハング:WCFクライアントはコンソールアプリケーション
var f = new DuplexChannelFactory<IService>(new Callback(), "NetTcpBinding_Name");
f.Credentials.ClientCertificate.Certificate = new X509Certificate2(certificateFile, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
f.Open();
IService s = f.CreateChannel();
Console.WriteLine("Lock status: " + s.IsUserLocked(id));
Task task = s.LockUserAsync(id);
Console.Write("Sent, awaiting ");
Console.WriteLine(task);
await task;
Console.WriteLine("Done");
Console.WriteLine("Lock status: " + s.IsUserLocked(id)); // never returns, timeout
非同期メソッドに待った後LockUserAsync
任意の同期方法は永遠にハングアップします。デバッガは、IsUserLocked
が実際に2回目と呼ばれ、その復帰に達したことを示しています。
他のクライアントには影響しません。接続して同じことを開始から繰り返すことができます。
行動:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
契約:
public async Task LockUserAsync(int id)
{
return;
}
public int IsUserLocked(int id)
{
return 0;
}
更新:
[ServiceContract(CallbackContract = typeof(IServiceCallback))]
public interface IService
{
[OperationContract]
Task LockUserAsync(int userId);
[OperationContract]
int IsUserLocked(int id);
}
public interface IServiceCallback
{
[OperationContract]
void TestCallback(); // not used
}
どちらの方法がちょうどプレースホルダーです、それはありませんので、同期コンテキストコンソールアプリケーションです。私がawait
を.Wait()
に置き換えた場合、それは機能します。 ConfigureAwait(false)
は何も変更されません。
私は、継続が何とか直接Task.SetResult
から呼び出されていることがわかりました。 ThreadPool
によって呼び出されないのはなぜですか?
コンソールアプリケーションで 'main'メソッドを' async'にすることはできません。したがって、すべての非同期メソッドを待つためには 'Main'メソッドの中で' .GetAwaiter()。GetResult() 'を呼び出さなければなりません完了する。もちろん、これらのasyncメソッドの中では、Webサービスを呼び出すときに 'await'キーワードを使うことができます。 –
@DarinDimitrovはい、私はすでにそうしています。そうでなければ、それはコンパイルされません。 – Vlad