2012-03-15 1 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]를 내 텍스트 상자와 목록에 바인더 제본 속성입니다.

사용자가 두 개의 문자를 입력하면 내 프로그램이 동시에 두 개의 스레드를 실행하게됩니다. 어떻게 쿼리를 중단 할 수 있습니까? 내가 생각하고


것들 :

이 부울 변수 IsQueryRuning를 생성하고 설정이 사실 quen 쿼리 시작 같고 스레드가 종료 될 때 거짓과 동일. 새 쿼리가 실행되고 IsQueryRuning = true이면 ObservableCollection = null을 설정하고 예외를 발생시킬 수 있습니다. 그런 다음 try catch 블록을 사용하여이 파일을 삭제합니다.

이 속성 컬렉션을 설정 = 널 가끔 내가해야했다 예외와 그렇지 않은 다른 시간 ...

답변

1

변경 가능한 경우 다른 방법을 제안합니다.

사용자의 각 키 입력을 쿼리하는 대신 예를 들어 3 자 후에 쿼리 만 수행합니다. 결과를 메모리의 일부 콜렉션에 보관하십시오.

그 후에는 메모리 내 컬렉션에서만 다음 쿼리를 수행하십시오. 따라서 데이터베이스 액세스가 항상 느려지고 성능이 상당히 향상됩니다.

0

원인 : 나는


편집 .. 기술이 가장 좋은 방법이 아니라고 생각 다음과 같은 쿼리를 실행하십시오.

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"); 
    } 
} 
관련 문제