私はWCFデータサービス内で 'AsyncPattern'を実装しようとしています。私はインターフェイスでBeginGetExperiments(...)とEndGetExperiments(...)の2つのメソッドを定義し、以下に示すようにメソッドを実装します。SQL Serverを呼び出すサーバー側のAsyncPattern
public class GmdProfileService : IGmdProfileService
{
IAsyncResult IGmdProfileService.BeginGetExperiments(AsyncCallback callback, object state)
{
//IAsyncResult res = Experiment.GetExperimentsAsync(callback, state, Properties.Settings.Default.gmdConnectionString);
//return res;
System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder(Properties.Settings.Default.gmdConnectionString);
csb.AsynchronousProcessing = true;
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(csb.ConnectionString);
conn.Open();
System.Data.SqlClient.SqlCommand cmd = conn.CreateCommand();
cmd = conn.CreateCommand();
cmd.CommandText = "SELECT id, name, comment, date, doi FROM tf.TagList WITH(NOLOCK) WHERE proprietary=0;";
cmd.CommandType = System.Data.CommandType.Text;
return new SqlCommandAsyncResult(cmd, callback, state);
}
public List<Experiment> EndGetExperiments(IAsyncResult result)
{
List<Experiment> res = new List<Experiment>();
SqlCommandAsyncResult myresult = result as SqlCommandAsyncResult;
using (System.Data.SqlClient.SqlDataReader reader = myresult.cmd.EndExecuteReader(myresult.originalState as IAsyncResult))
{
try
{
while (reader.Read())
{
res.Add(new Experiment(reader));
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
// Closing the reader also closes the connection, because this reader was created using the CommandBehavior.CloseConnection value.
if (reader != null)
{
reader.Close();
}
}
}
return res;
}
BeginGetExperiments後でアクセスするための私のSqlCommand
への参照を保持していることに加えてIAsyncResult
インタフェースを実装するクラスSqlCommandAsyncResult
を返します。
私が直面する困難は、EndGetExperiments
の方法にあります。私はSqlCommand
にアクセスしてEndExecuteReader(...)
に電話する方法を知らない。 通常、私はBeginExecutereader
の状態オブジェクトを使用してコマンドを渡します。しかし、私がそうした場合、例外が発生します: "IAsyncResultの状態は、Begin呼び出しに渡される状態引数でなければなりません。"
IAsyncResultを使用して、SqlCommandをEndGetExperiments
に転送しようとしました。ここで、私が理解していない点は、EndGetExperiments
の場合、変数結果は、SqlCommandAsyncResult
クラスのCompletedSynchronously
の値に応じてタイプIAsyncResult
またはタイプSqlCommandAsyncResult
のいずれかであることです。 CompletedSynchronously = false
を設定すると、SqlCommandにアクセスできないのでコードが失敗するCompletedSynchronously = true
コードは魅力的に機能しますが、何かが間違っている可能性があるという奇妙な感覚があります。
私は、このコードを動作させるための助けと指針とサンプルコードをお寄せいただきありがとうございます。
ありがとうございました。 Jan
@tonyjyありがとうございましたが、お勧めのパターンは、[OperationContractAttribute()のBeginMyMethod(...)EndMyMethod(...)パターンと互換性がありますか? AsyncPattern = true)] 'wcfデータサービス? – jahu
私はそれがあなたが達成しようとしている目標に依存すると思います。 WCFに電話をかけている間にクライアントがブロックせずに実行されるようにしようとしている場合。サーバーは同期として実装でき、クライアントは非同期で使用できます。タスクは、TreadPoolまたはConcurrentContextのクライアント側で非常に便利です。 –
tonyjy
もう一度ありがとうございます。よくわかりません。上に掲げたコードは、明らかにサーバー側で実行されています。私が把握しようとしているのは、ベストプラクティステクノロジを使用してwcfデータサービスの**サーバー側**を実装して、SQlサーバーからデータを取り出してクライアントに転送する方法です。私はここに表示される 'AsyncPattern = true'に従います。[link](http://msdn.microsoft.com/en-us/library/ms731177.aspx)。これまでのところ、私はサーバー側についてしか話していません。 – jahu