6

タスクバーに配置され、(SQLConnectionを介して)データベースを定期的にチェックするアプリケーションがあります。データベースに到達できない場合は、通知アイコンに赤いステータスが表示されるだけで、他には何も表示されません。これは、ユーザーが施設間を移動するラップトップを使用し、データベースにアクセスできるのは内部ネットワーク上またはVPN経由で接続されている場合のみであるためです。

私が抱えている問題は、データベースにアクセスできない場合でも、通知アイコンのコンテキストメニューが応答するようにしたいということです。現在、データベースが接続を試みているときにユーザーがメニューを操作しようとすると、接続の試行によってスレッドがロックされます。

私が望んでいるのは、データベース接続が別のスレッドで行われることですが、スレッド間で接続オブジェクトを共有することは悪いことであることを私は知っています。データベースが接続されたら、元のスレッドからデータベースをクエリする必要があります。これを行うための良い方法はありますか?

新しいスレッドでrusを実行し、接続が失敗したかどうかを確認するだけの関数を使用できることはわかっています。それで成功した場合は、元のスレッドが移動して独自のデータベースオブジェクトに接続できます。しかし、その方法は悪い回避策のようです。アイデア?

ありがとう!


提案をありがとう-私はそれらからかなりのことを学びました。結局、最初からやるべきことをやった。メイン(UI)スレッドは、定期的なデータベース更新が必要な場合はいつでも、新しいスレッド(データベースオブジェクトの作成と接続を含む)を開始するだけです。

したがって、HenkHoltermanが元のメッセージへのコメントで提案したように、データベースを作成して別のスレッドで操作を実行する必要はありませんでした。

VS2010にアップグレードしたら、SqlConnection.OpenAsyncの使用に間違いなく興味があります。

再度、感謝します。

4

3 に答える 3

7

ASqlConnectionにはスレッド アフィニティ要件がないため、別のスレッドで作成して開き、参照を UI スレッドに戻すことができます。複数のスレッドから同じインスタンスのプロパティやメソッドを同時に呼び出さない限り、問題は発生しません。

クラス (System.Threading.Task) を使用してTaskこの操作をバックグラウンドで開始し、呼び出しContinueWithてインスタンスの所有権を UI スレッドに戻します。

public class TrayIconForm : Form
{
  private SqlConnection connection = null;

  private void Form_Load(object sender, EventArgs args)
  {
    TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();

    Task.Factory.StartNew(() =>
      {
        var sql = new SqlConnection();
        sql.ConnectionString = "your connection string";
        sql.Open();
        return sql;
      }).ContinueWith((task =>
      {
        connection = task.Result;
        // You can access other UI elements here as needed.
      }), ui);
  }
}

C# 5.0 で導入され、Async CTP を介して現在利用可能な新しいasyncandawaitキーワードを使用すると、これを行うことができます。

private async void Form_Load(object sender, EventArgs args)
{
  connection = await Task.Run(() =>   // TaskEx.Run in the CTP
    {
      var sql = new SqlConnection();
      sql.ConnectionString = "your connection string";
      sql.Open();
      return sql;
    });
}
于 2012-04-18T18:24:44.727 に答える
2

新しいC# Async CTP を使用することをお勧めします。 これにより、UI スレッドにとどまることができるため、複雑さが軽減されます。

SqlConnection.OpenAsync

于 2012-04-18T16:22:16.393 に答える
1

BackgroundWorkerオブジェクトを使用すると、簡単な方法で問題を解決できますが、より正確には、スレッドを使用して接続を開き、UI スレッドがユーザー入力を受け取る準備ができたままにする必要があります。

于 2012-04-18T16:21:18.730 に答える