2012-04-14 5 views
0

Ich habe mein Programm in 3 Schichten aufgeteilt; GUI, BL, IO und versuchte, Dateien von meinem Server zu meinem PC zu grapieren. Ich habe es multi-threaded gemacht und zorks gut, aber als ich versuchte, einen Delegaten hinzuzufügen, um Nachrichten von meinem IO zu meiner GUI zu senden, stört es mich. Es wird gesagt, etwas wie:invalidOperationException bei der Verwendung von Delegaten im Thread

Es ist keine Operation durch verschiedene Threads auszuführen erlaubt: es ist von einem anderen Thread Zugriff auf die Herunterladesteuer Etikett hatte Fortschritt als das Gewinde, auf das das Element angelegt wird.

Was ich habe, ist dies:

GUI

private void buttonDownload_Click(object sender, EventArgs e) 
{ 
    download = new BL_DataTransfer(Wat.FILM, titel, this.downloadDel); 
    t = new Thread(new ThreadStart(download.DownLoadFiles));  
    t.Start(); 
} 
private void UpdateDownloadLabel(string File) 
{ 
     labelDownloadProgress.Text = "Downloading: " + File; 
} 

BL

public void DownLoadFiles() 
    { 
     //bestanden zoeken op server 
     string map = BASEDIR + this.wat.ToString() + @"\" + this.titel + @"\"; 
     string[] files = IO_DataTransfer.GrapFiles(map); 

     //pad omvormen 
     string[] downloadFiles = this.VeranderNaarDownLoadPad(files,this.titel); 
     IO_DataTransfer.DownloadFiles(@".\" + this.titel + @"\", files, downloadFiles, this.obserdelegate); 
    } 

IO

public static void DownloadFiles(string map, string[] bestanden, string[] uploadPlaats, ObserverDelegate observerDelegete) 
    { 
     try 
     { 
      Directory.CreateDirectory(map); 

      for (int i = 0; i < bestanden.Count(); i++) 
      { 
       observerDelegete(bestanden[i]); 
       File.Copy(bestanden[i], uploadPlaats[i]); 
      } 
     } 
     catch (UnauthorizedAccessException uoe) { } 
     catch (FileNotFoundException fnfe) { } 
     catch (Exception e) { }   
    } 

Delgate

public delegate void ObserverDelegate(string fileName); 

Antwort

0

wenn UpdateDownloadLabel Funktion in einem gewissen Steuercode-Datei, Muster wie folgt verwenden:

private void UpdateDownloadLabel(string File) 
{ 
    this.Invoke(new Action(()=> { 
      labelDownloadProgress.Text = "Downloading: " + File; 
     }))); 
} 

Sie benötigen Zuordnung auf UI-Thread, um aufrufen zu können, etwas auf dem Etikett ändern.

+0

ooh nett! Danke, funktioniert –

1

Angenommen, es ist die Aktualisierung der Beschriftung, die fehlschlägt, müssen Sie das Ereignis auf den UI-Thread marshalieren. Um diese Änderung zu tun, um Ihr Update-Code zu sein:

private void UpdateDownloadLabel(string File) 
{ 
    if (labelDownloadProgress.InvokeRequired) 
    { 
     labelDownloadProgress.Invoke(new Action(() => 
      { 
       labelDownloadProgress.Text = "Downloading: " + File; 
      }); 
    } 
    else 
    { 
     labelDownloadProgress.Text = "Downloading: " + File; 
    } 
} 

Ich habe am Ende der Schaffung eine Erweiterungsmethode für diese, die ich anrufen kann - so die Menge des wiederholten Code in meinen Anwendungen zu reduzieren:

public static void InvokeIfRequired(this Control control, Action action) 
{ 
    if (control.InvokeRequired) 
    { 
     control.Invoke(action); 
    } 
    else 
    { 
     action(); 
    } 
} 

Was heißt dann so:

private void UpdateDownloadLabel(string File) 
{ 
    this.labelDownloadProgress.InvokeIfRequired(() => 
     labelDownloadProgress.Text = "Downloading: " + File); 
} 
Verwandte Themen