2010-01-10 3 views
0

J'ai une instruction try-catch en référence au téléchargement d'un fichier. Lorsque le fichier est téléchargé, j'active ensuite l'un de mes éléments de menu, puis j'éteins une minuterie pour réessayer le téléchargement en une minute.Option de menu d'activation C#

Mon problème est que, pour une raison quelconque, ma ligne trafficManagementToolStripMenuItem.Enabled = true; active l'instruction catch même si l'élément de menu est activé. Le fichier est téléchargé correctement et quand je commente cette ligne, cela fonctionne parfaitement. Mais chaque fois que je l'exécute, j'obtiens la boîte de message "erreur" et la minuterie n'est pas désactivée même si l'élément de menu s'activera correctement une fois le téléchargement terminé.

Des idées?

try 
{ 
    ////downloads Data 

    string address = "http://website.file.txt"; 
    string filename = "vsd.txt"; 
    WebClient client = new WebClient(); 
    client.DownloadFile(address, filename); 
    trafficManagementToolStripMenuItem.Enabled = true; 
    timer1.Enabled = false; 
} 
catch 
{ 
    timer1.Enabled = true; 
    MessageBox.Show("error", "test"); 
} 
+1

Est-ce code en cours d'exécution sur un thread autre que le thread GUI principal? – wj32

+0

peut-être d'abord voir quelle est l'exception? – Danail

+0

oui c'est en arrière-plan. Ce qui est étrange, c'est que la seconde fois qu'il fonctionne (après que la minuterie l'ait redémarré), il fonctionne parfaitement. – Brodie

Répondre

4

Vous ne dites pas quelle est l'exception, mais je suppose que vous exécutez votre routine de téléchargement dans un thread d'arrière-plan, n'est-ce pas? Vous pouvez uniquement accéder aux contrôles à partir du thread qui les a créés: le thread principal de l'interface utilisateur. L'accès à un contrôle tel qu'un ToolStripMenuItem à partir d'un thread d'arrière-plan provoquera une exception.

Si tel est le cas, utilisez la méthode Control.Invoke ou Control.BeginInvoke pour exécuter l'appel .Enabled = true sur l'unité d'exécution de ToolStripMenuItem. Pour ce faire, vous aurez besoin d'un contrôle (malheureusement ToolStripMenuItem est seulement un composant). Je suppose que vous pouvez obtenir une référence au formulaire contenant quelque part. Maintenant, vous pouvez écrire ceci:

Action enableAction = delegate() { trafficManagementToolStripMenuItem.Enabled = true; } 
form.BeginInvoke(enableAction); 

Cela provoque le enableAction à exécuter sur le thread d'interface utilisateur correcte pour form.

+0

J'utilise mes pouvoirs psychiques pour prédire le débogage pychique d'itowlson va résoudre le problème. – RedDeckWins

+0

* Ne jamais utiliser Invoke. Commencez toujours Invoke. – wj32

+1

"Jamais" est trop fort. Mais vous avez raison, il est bon de prendre l'habitude d'utiliser BeginInvoke à moins qu'il n'y ait une raison spécifique de préférer Invoke. Je vais mettre à jour l'exemple. – itowlson

4

changer votre capture à

catch (Exception ex) 
{ 
    timer1.Enabled = true; 
    MessageBox.Show("error", ex.Message); 
} 

Cela vous donnera sera au moins le message d'erreur réelle.

Je devine que c'est parce que vous n'êtes pas en cours d'exécution dans le thread d'interface utilisateur et que vous devez utiliser Control.Invoke, jetez un oeil à http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx sur msdn

+0

J'ai lu le lien et compris le problème, mais je suis trop nouveau pour comprendre ce que je dois faire pour le faire fonctionner dès le premier essai. – Brodie

+0

-1: N'utilisez pas ex.Message, utilisez ex.ToString(). –

+0

essayer .... action Action = nouvelle action (() => { trafficManagementToolStripMenuItem.Enabled = true; Timer1.Enabled = false;} ; si (trafficManagementToolStripMenuItem.InvokeRequired) { trafficManagementToolStripMenuItem.Invoke (action); } else { action(); } –

Questions connexes