2012-04-14 5 views
0

私は3つのレイヤーでプログラムを分割しました。 GUI、BL、IOと私のサーバーから私のサーバーにファイルをgrapしようとしました。私はそれをマルチスレッドとzorksにしましたが、私のIOから私のGUIにメッセージを送るためにデリゲートを追加しようとしたとき、それは私を悩ませました。スレッド内でデリゲートを使用中にinvalidOperationExceptionが発生しました

それは、さまざまなスレッドを通じて操作を実行することはできません:それは何かのように言った別のスレッドが要素が作成されたスレッド以外 進捗をダウンロード制御ラベルへのアクセスを持っていたから、それ でした。私が持っているもの

はこれです:

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); 

答えて

0

UpdateDownloadLabel機能は、いくつかの制御コード・ファイル内にある場合、このような使用パターン:

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

あなたがラベルに何かを変更することができるようにするために、UIスレッド上の割り当てを起動する必要があります。

+0

ooh nice!感謝はgreateを働かせます –

1

あなたが失敗したラベルの更新であると仮定すると、イベントをUIスレッドにマーシャリングする必要があります。これを行うには、あるためにあなたの更新コードを変更:

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

私は呼び出すことができ、このための拡張メソッドの作成終わっている - ので、私のアプリケーションで繰り返しコードの量を減らすことを:

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

これは次のように呼び出されます。

private void UpdateDownloadLabel(string File) 
{ 
    this.labelDownloadProgress.InvokeIfRequired(() => 
     labelDownloadProgress.Text = "Downloading: " + File); 
} 
関連する問題