11

次のようなEF 6asyncクエリ機能を使用しています

var list = await cx.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();

データベース内のデータが変更されたときに通知を受け取ることができるように、これらのクエリに対する SQL の依存関係も開始したいと考えています。System.Runtime.Remoting.Messaging.CallContext次のように使用してこれを行うことができます。

    async Task GetData()
    {
        using (ClientsContext context = new ClientsContext()) // subclass of DbContext
        {

            SqlDependency.Start(context.Database.Connection.ConnectionString);
            SqlDependency dependency = new SqlDependency();
            dependency.OnChange += (sender, e) =>
                {
                    Console.Write(e.ToString()); 
                };

            System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
            var list = await context.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();
        }
    }

..そしてそれはうまくいきます。SqlDependencyしかし、複数のクエリを実行したい場合、問題が発生しています。上記のような2 つのasyncメソッドがGetData()あり、両方を同時に実行すると、最初のメソッドだけが変更通知を受け取ります。これは、CallContext が各メソッドによって設定された Cookie を連続して保持しているためであると想定しています。最初のメソッドが完了するのを待ってからasync2 番目のメソッドを呼び出すと、両方とも期待どおりに変更通知を受け取ります。これに対する解決策はありますか?

4

1 に答える 1

11

私は SqlDependency にあまり詳しくありませんが、以下では、ToListAsync が呼び出されたときに (複数の呼び出しが実行されている場合)、CallContext が正しい値を持つことができます。ここでの概念実証、https://dotnetfiddle.net/F8FnFe

    async Task<List<Client>> GetData()
    {
        using (ClientsContext context = new ClientsContext()) // subclass of DbContext
        {
            SqlDependency.Start(context.Database.Connection.ConnectionString);
            SqlDependency dependency = new SqlDependency();
            dependency.OnChange += (sender, e) =>
            {
                Console.Write(e.ToString());
            };

            Task<List<Client>> task = Task<Task<List<Client>>>.Factory.StartNew(async () =>
            {
                System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
                var list = await context.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();
            }).Unwrap();

            return await task;
        }
    }
于 2014-06-03T22:41:59.660 に答える