2012-03-15 18 views
0

私はオートコンプリートコントロールを実装しています。ユーザーが入力に新しい文字を入力するたびに、クエリが実行されます。テストするために、私は、平均クエリが実行するのに約5秒かかる大規模なデータベースを作成しました。ado.netクエリを中止する

問合せは、私は新しいスレッドでクエリを実行実行する5秒かかりますので:

// execute the following lamda expression when user enters characters to textbox 
    textBox1.TextChanged +=(x,eventArgs)=>{ 

      // execute query on separate thread 
      new Thread(new ThreadStart(() => 
      { 
       ObservableCollection = MyEntities.Entities.Products.Where(p => p.Name.Contains(inputText)); 
      })).Start(); 
    }; 

のObservableCollectionとのinputTextが私のテキストボックスとリストにバインドさプロパティです。

問題は、ユーザーが2文字を入力すると、プログラムは同時に2つのスレッドを実行することになります。クエリを中止するにはどうすればよいですか?私が考えてい


もの:

ブール変数IsQueryRuningを作成し、スレッドが終了したときに真quenクエリが開始に等しいとfalseに等しく、それを設定します。新しいクエリが実行され、IsQueryRuning = trueの場合、ObservableCollection = nullを設定して例外を発生させることができます。私はtry catchブロックでそれを再開します。私が持っていた

答えて

1

これはあなたのために変更することができます場合は、私は別のアプローチをお勧めします。

ユーザーの各キーストロークを照会するのではなく、たとえば3文字後にのみクエリを実行します。結果をメモリ内のコレクションに保存します。

その後、メモリ内のコレクションの次のクエリのみを実行します。これにより、データベースのアクセスが常に遅くなり、パフォーマンスが大幅に向上するはずです。

0

...プロパティのコレクションを設定

は、= nullは、時にはそれがない例外や他のいくつかの時間が発生します。私は技術が最善のアプローチではないと思われる。..


編集

public IEnumerable<T> ExecuteQuery(IEnumerable<T> query) 
    { 
     foreach (var t in query) 
     { 
      if (counterOfSymultaneosQueries > 1) 
      { 
       // if there are more than two queries break from the last one 
       // breaking from it will decrease counterOfSymoltanosQueries 
       break; 
      } 
      yield return t; 
     } 
    } 
0
class Program 
{   
    public class Person 
    { 
     public string Name; 
     public int Age; 
    }   

    public static void ExecuteQueryAsync (IEnumerable<Person> collectionToQuery , Action<List<Person>> onQueryTerminated , out Action stopExecutionOfQuery) 
    { 
     var abort = false; 

     stopExecutionOfQuery =() => 
     { 
      abort = true; 
     };    

     Task.Factory.StartNew(() => 
     { 
      try 
      { 
       var query = collectionToQuery.Where(x => 
       { 
        if (abort) 
         throw new NotImplementedException("Query aborted"); 

        // query logic: 
        if (x.Age < 25) 
         return true; 
        return 
         false; 
       }); 

       onQueryTerminated(query.ToList()); 

      } 
      catch 
      { 
       onQueryTerminated(null); 
      } 
     }); 
    } 


    static void Main (string[] args) 
    { 
     Random random = new Random(); 

     Person[] people = new Person[ 1000000 ]; 

     // populate array 
     for (var i = 0 ; i < people.Length ; i++) 
      people[ i ] = new Person() { Age = random.Next(0 , 100) }; 

     Action abortQuery; 
     ExecuteQueryAsync(people , OnQueryDone , out abortQuery); 

     // if after some time user wants to stop query: 
     abortQuery(); 

     Console.Read(); 
    } 

    static void OnQueryDone (List<Person> results) 
    { 
     if (results == null) 
      Console.WriteLine("Query was canceled by the user"); 
     else 
      Console.WriteLine("Query yield " + results.Count + " results"); 
    } 
} 
関連する問題