1

私はスレッド化に比較的慣れていないので、これを正しく行っているかどうかはわかりません。

私の現在のアプリケーションでは、マルチタブのナビゲーション フォームがあり、その一部には他のフォームにつながるボタンがあり、一部にはテーブルがあり、一部には両方があります。そのようなものには、エントリを追加するボタンと、ストアド プロシージャを介してプルされたその日のすべてのエントリを示すテーブルがあります。

その 2 番目のフォームをダイアログとして開いたとき、作成したメソッドを呼び出してテーブルを更新するのは簡単でしたが、そのように遅くなりました。代わりに、信じられないほど高速に実行される別のスレッドとして呼び出しを開始しましたが、スレッドが終了したときにメソッドを呼び出す方法が見つからないようです。しばらく検索しましたが、有効な解決策が見つかりませんでした。

コードは次のとおりです。

public static void ThreadProcAddEntry()
    {
        Application.Run(new AddEntry());
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        System.Threading.Thread t = new Thread(new ThreadStart(ThreadProcAddEntry));
        t.Name = "AddEntry";
        t.Start();           
    }

public void GetMyEntries(string username)
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DB2"].ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand("SP_GetUserEntries", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("@UserID", SqlDbType.VarChar).Value = username;
                conn.Open();
                cmd.ExecuteNonQuery();
                SqlDataReader reader = cmd.ExecuteReader();

                using (reader)
                {
                    DataTable table = new DataTable();
                    table.Load(reader);
                    dgvMyEntry.DataSource = table;
                    dgvMyEntry.AllowUserToAddRows = false;
                    dgvMyEntry.ReadOnly = true;
                    dgvMyEntry.AutoResizeColumns();
                    dgvMyEntry.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                }
            }
        }

    }

AddEntryForm の [Submit] ボタンをクリックするとすぐに発生する (SQL に送信した後、dispose メソッドを実行する) スレッドの終了時に GetMyEntries メソッドを実行することをどのように提案しますか?

4

5 に答える 5

2

次のように、タスクを使用することをお勧めします。

await Task
    .Run(() => ThreadProcAddEntry())
    .ContinueWith(task => GetMyEntries(username));

これは生のスレッドやバックグラウンド ワーカーを使用するよりも簡潔で読みやすいです。

GetMyEntries完了するとすぐに実行されThreadProcAddEntryます。

タスク並列ライブラリ (async/await) の詳細: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

于 2013-08-29T14:53:21.460 に答える
2

.NET フレームワークによって提供される別のラッパー メソッド/インターフェイスを使用できます。それがBackgroundWorkerです。詳細については、msnd http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspxを確認してください。

var backgroundWorker = new BackgroundWorker();

// define the event handlers
backgroundWorker.DoWork += (sender, args) => {
    // do your lengthy stuff here -- this will happen in a separate thread
    ...
}
backgroundWorker.RunWorkerCompleted += (sender, args) => {
    if (args.Error != null)  // if an exception occurred during DoWork,
        MessageBox.Show(args.Error.ToString());  // do your error handling here

    // Do whatever else you want to do after the work completed.
    // This happens in the main UI thread.
    ...
}

backgroundWorker.RunWorkerAsync(); // starts the background worker
于 2013-08-29T14:46:53.300 に答える
0

生の Thread を使用するのではなく、.net が提供する便利なスレッド ラッピング クラスの 1 つを使用できます。具体的には、これはBackgroundWorkerにとって完璧な仕事のように思えます。新しい BackgroundWorker を作成し、スレッドで実行するコードを BackgroundWorker の DoWork イベントに追加し、GetMyEntries を BackgroundWorker の RunWorkerCompleted イベントに追加してから、RunWorkerAsync() を呼び出します。

于 2013-08-29T14:46:37.767 に答える