2009-03-04 5 views

Répondre

2

Ainsi, selon le commentaire de Richard Szalay:

Votre meilleur pari est d'exécuter la requête dans un thread d'arrière-plan et simplement résilier votre abonnement de les événements de l'objet conteneur lorsque l'utilisateur clique sur Annuler.

Et je pense que je suis d'accord pour dire que c'est un bon travail pour le moment. Ce que j'aimerais voir, c'est une fonctionnalité de requête Async déjà dans le framework, mais jusqu'à ce que cela se produise, cela devra être fait.

ont pas commencé à mettre en œuvre ce encore (doivent terminer d'autres choses d'abord), mais d'une façon il pourrait fonctionner:

  • Dans le fil de travail, faire les requêtes dans un thread de requête séparée puis Joignez ce fil jusqu'à ce qu'il soit terminé.
  • Lorsque l'utilisateur clique sur annuler, appelez la méthode Interrupt du thread de travail, qui obtiendrait alors un et cesserait d'attendre la fin du thread de requête.

pouvez ajouter un code plus tard, quand je le fais. Mais nous verrons comment il se trouve à peu: p

+0

Je recommande contre cette solution. L'utilisation de ThreadInterruptedException est tout aussi mauvaise que l'utilisation de Thread.Abort. Je recommande de lire l'article que j'ai posté dans mon commentaire à la réponse de Kieron. –

+0

Peut-être aller dans une boucle et vérifier un drapeau ou quelque chose alors? Et puis juste revenir et ne pas attendre le résultat si l'utilisateur veut annuler? – Svish

-1

Je dirais que vous auriez probablement besoin de l'exécuter sur un thread distinct et l'annuler à la place.

+0

comment pouvez-vous annuler un fil? – Svish

+0

Je ne recommande pas de descendre ce chemin. L'utilisation de Thread.Abort est une mauvaise pratique et ne garantit même pas l'abandon du thread. Voir http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx –

+0

ouais, je voulais lire quelque chose comme ça aussi. – Svish

2

Si vous définissez la propriété CommandTimeout (secondes) de DataContext, une exception est automatiquement levée une fois le délai écoulé.

+0

Mais pouvez-vous le définir pendant l'exécution d'une requête? – Svish

+0

à partir d'un fil différent? – Svish

+0

Non - vous devez le définir avant le début de la commande. Je ne suis pas sûr du comportement défini pour le modifier pendant l'exécution d'une requête. –

0

Je sais que cette réponse est un peu en retard, mais voici comment je le fais:

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"); 
    } 
} 
Questions connexes