2012-04-14 97 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); 
}