0

こんにちはGurus私はフォームにDataGridViewオブジェクトを持っています。サービスクラスには、次のようなメソッドがあります。

Form.CheckForIllegalCrossThreadCalls = false;
Thread tr1 =
    new Thread(() =>
    {
        List<Musteri> list = null;
        IEnumerable<Musteri> result = from Musteri m in Db4OService.Database
                                      where (
                                                m.servisAdi.Contains(text) ||
                                                m.il.Contains(text))
                                      select m;
       list = result.ToList<Musteri>();


        DataGridView dataGridView = ((DataGridView)sayfa.Controls.Find("dataGridView1", false)[0]);
        DataTable dt = ListToDataTable(list);
        try
        {
            dataGridView.DataSource = dt;
            dataGridView.Refresh();
        }
        catch (Exception e)
        {
                Console.Write(e);

        } 

    });
tr1.Start();

このメソッドは、textBoxのtextChangedメソッドから毎回呼び出します。なので、タイピングをスムーズにしたいと思います。1つのスレッドですべての作業を行う場合、検索メソッドが終了して別の文字を入力するのを待つ必要があります。私のアプローチはうまくいきません:(どんな助けでも歓迎します。ありがとう!!

4

3 に答える 3

0
Form.CheckForIllegalCrossThreadCalls = false;

これは悪いことです。使用しないようにしてください。決して決して決して決して決して。呼び出しについて読んでください。

于 2013-10-08T08:41:06.810 に答える
0

作業を分離し、 BackgroundWorker クラスを使用して別のスレッドで実行する必要があり ます

于 2012-07-28T21:59:17.310 に答える
0

ここで英語を取り上げようとしているわけではありませんが、投稿にあるコードが TextChangedEvent で呼び出されるのか、コードが TextChangeEvent を生成するのかは明確ではありません。また、そのコードはぎくしゃくしたタイピングでも機能しますか? コードに問題があると思います。

  1. 提供されたコードが TextChangedEvent で呼び出され、データベースからデータを検索してグリッドに入力すると仮定します。
  2. 非 GUI スレッドからグリッドを更新しようとしているようです。まず、非 GUI スレッドから GUI を更新するのは悪い考えです。
  3. あなたが何をしたいのかを私が理解していることから、このスレッドを実際に追跡可能な変数にすることをお勧めします。そのため、ユーザーがテキストを入力し、検索がまだ返されない場合は、ユーザーがさらに入力した可能性があるため、DB ルックアップ。要するに、ユーザーが入力すると検索基準と表示結果が変わる可能性があるため、検索とグリッドの更新をキャンセルできるはずです。そうしないと、ユーザーが興味を失ったものを検索するために単にリソースを浪費することになります。

以下は、私がそれをコーディングする方法です:

bool searching = false;
object searchThreadLock = new object();
Thread searchThread = null;

void TextChangedEvent() {
    lock (searchThreadLock) {
        if (searching && searchThread != null && searchThread.IsAlive)
            searchThread.Abort();

        lookupForData();
    }
}

void lookupForData() {
    searchThread = new Thread( () => {
        // Your code to retrieve relevant data from DB based on your TextChangedEvent goes here
        searching = true;
        try {
            List<Musteri> list = null;
            IEnumerable<Musteri> result = 
                from Musteri m in Db4OService.Database
                    where (
                        m.servisAdi.Contains(text) ||
                        m.il.Contains(text))
                    select m;
            list = result.ToList<Musteri>();
            DataTable dt = ListToDataTable(list);
            updateGrid(dt);
        } catch (ThreadAbortException ex) {
        } finally {
            searching = false;
        }
    } );
    searchThread.start();
}

void updateGrid(DataTable dt) {
    DataGridView dataGridView = ((DataGridView)sayfa.Controls.Find("dataGridView1", false)[0]);
    if (dataGridView.InvokeRequired) {
        dataGridView.BeginInvoke(new Action<DataTable>(updatdeGrid), dt);
        return;
    }

    // Your code to update the grid goes here
    dataGridView.DataSource = dt;
    dataGridView.Refresh();
}

PS: Thread.Abort は一般的に悪い考えであり、DB 検索を停止するアプリ固有のロジックに置き換える必要があることに注意してください。LINQクエリを正しく停止する方法がわからないため、それを配置しました。

于 2012-07-28T23:43:25.990 に答える