2

大きな問題があります。Windows フォームに SqlDependency ウォッチャーを実装すると、「OnChance」イベントを UI スレッドに呼び出す限り、すべて正常に動作します。

private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
  if (this.InvokeRequired)
  {
    OnChangeEventHandler tempDelegate = new OnChangeEventHandler(dependency_OnChange); object[] args = { sender, e };
    this.Invoke(tempDelegate, args);
    return;
  }

  SqlDependency dependency = (SqlDependency)sender;
  dependency.OnChange -= dependency_OnChange;
  SetSqlWatcher();
}

メソッドをクラスに移動すると、クラスが ISynchronizeInvoke を実装していないため、Invoke と InvokeRequired を実行できません。これらの行にコメントを付けると、プログラムは "SetSqlWatcher" の最初の行でハングします。

SqlDependency.Stop("Data Source=[....]");

Windowsフォームでこれらの行にコメントを付けると同じことが起こるので、_OnChance イベントは、初めて SetSqlWatcher を呼び出したときに使用している「スレッド」とは別のスレッドにあると思います。

また、ISynchronizeInvoke を実装しようとしました (ライブラリhttp://nitoasync.codeplex.comの GenericSynchronizingObject の助けを借りて)。コードが最初にそれを呼び出す必要があることをデバッグしましたが、「SqlDependency.Stop」でもハングします...

誰かが私を助けることができますか、そしてなぜこれがうまくいかないのか説明してくれますか?

どうもありがとうございました!よろしくトーマス

4

1 に答える 1

2

ええ、私はそれを自分で見つけました:)誰かが同じ問題に遭遇した場合:SqlDependencyを再起動する必要があるときにAutoResetEventで「通知」される独自のスレッドを使用して解決しました:

private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
  SqlDependency dependency = (SqlDependency)sender;
  dependency.OnChange -= dependency_OnChange;
  autoEvent.Set();
}

public void ThreadWorker(object data)
{
  while (true)
  {
    SetSqlWatcher();

    autoEvent.WaitOne();
  }
}
于 2011-03-16T12:51:23.920 に答える