2012-04-14 48 views
0

我將程序分爲3層;圖形用戶界面,BL,IO,並試圖從我的服務器上抓取文件到我的電腦。我做了多線程和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很好!感謝作品格林 – 2012-04-14 12:14:34

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