2009-08-05 8 views
2

À l'heure actuelle, j'ai une application Windows (C#) qui crache des rapports de longue durée. Chaque rapport extrait certaines informations de l'interface utilisateur pour limiter les rapports. Bien sûr, la création du rapport se passe sur un thread d'arrière-plan et j'ai besoin d'appeler correctement les différents contrôles pour obtenir des choses comme les index et les valeurs sélectionnés. Mais je ne pense pas que mon code semble bon et j'espérais qu'il y avait un meilleur modèle. Parce qu'il ya tellement de demandes de contrôles, j'ai fait les délégués génériques pour chaque type qui serait retourné:Nettoyer les motifs Invoke?

private delegate string StringDelegate(); 
private delegate int IntDelegate(); 

plus bas, il y a plusieurs instanciations de ces délégués:

private StringDelegate GetYearSelectedItem = new StringDelegate(cmbYearAsync); 

YearAsync ressemble à ceci :

private string cmbYearAsync() { 
    return cmbYear.SelectedItem.ToString(); 
} 

Et enfin, dans le code qui est sur un thread d'arrière-plan, voilà comment je reçois les valeurs:

cmbYear.Invoke(GetCmbYearSelectedItem); 

Existe-t-il un moyen plus simple d'obtenir ces valeurs à partir d'un thread séparé?

Répondre

2

En supposant que vous vouliez aller avec le design à threads (peut-être que vous voulez que les threads d'arrière-plan signalent des résultats partiels à l'interface utilisateur lorsqu'ils s'exécutent?), Si vous avez C# 3, vous pouvez certainement le rogner un peu. Certaines personnes trouvent une méthode d'extension comme cela utile:

public static class ControlExtensions 
{ 
    public static T Invoke<T>(this Control ctrl, Func<T> func) 
    { 
     if (ctrl.InvokeRequired) 
      return (T) ctrl.Invoke(func); 

     return func(); 
    } 
} 

En plus de vérifier si l'appel doit être classé, il est également le paramètre délégué typesafe. Vous pouvez donc écrire:

string selected = comboBox1.Invoke(() => comboBox1.SelectedItem.ToString()); 

Pas besoin de pré-déclarer tous ces autres éléments. Il suffit d'écrire le code habituel que vous écririez mais à l'intérieur de ce motif lambda.

Vous pouvez écrire une méthode d'extension similaire qui prend Action au lieu de Func<T> et renvoie void pour les opérations qui n'ont pas besoin d'une valeur de retour.

4

réponse courte

Ne fais pas ça ;-)

longue réponse

rassembler les paramètres du rapport de l'interface utilisateur contrôle à l'avant (peut-être dans une petite classe) et les passer à la rapports dans les fils fond

Ceci élimine le contre-thread appelle aux commandes de l'interface utilisateur, et découple les paramètres du rapport de l'interface utilisateur