2014-05-23 47 views
1

我正在圈子搜索和阅读论坛如何解决这个问题。经过一天的尝试,我仍然不知如何解决我的问题。我上传了一个文件,需要在文本框中返回%。我对上传部分没有任何问题,如果将所有代码都包含在同一个类中,则使用BackgroundWorker返回值时不会出现问题。然而,我正在做的是从form1调用一个ftp类。我需要ftp类将百分比返回给form1,以便我可以在我的UI中显示,并且还需要从我的ftp类返回的服务器响应代码显示在我的form1中。在我尝试在BackgroundWorker进程中运行此操作之前,一切正常,除了UI无响应并在上传完成后返回所有状态消息。下面是我的代码,因为它现在。如何从ftp类获得百分比并将其传回form1以及服务器响应代码一旦完成?不同类别的BackgroundWorker ReportProgress

public partial class Form1 : Form 
{ 
    private BackgroundWorker bw = new BackgroundWorker(); 
    private string ftpServer = @"ftp://10.0.0.0"; 
    private string ftpUser = @"user"; 
    private string ftpPass = @"pass"; 
    private string ftpRemoteFile = @"myfile.exe"; 
    private string ftpLocalFile = @"C:\Uploads\file.exe"; 

    public Form1() 
    { 
     InitializeComponent(); 
     bw.WorkerReportsProgress = true; 
     bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
     bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
    } 

    private void sendButton_Click(object sender, EventArgs e) 
    { 
     progressRichTextBox.Text = "Sending"; 
     if (bw.IsBusy != true) 
     { 
      bw.RunWorkerAsync(); 
     } 
    } 

    private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 

     ftp ftpClient = new ftp(ftpServer, ftpUser, ftpPass); 
     ftpClient.upload(progressRichTextBox, ftpRemoteFile, ftpLocalFile); 
    } 
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (!(e.Error == null)) 
     { 
      this.progressRichTextBox.Text = ("Error: " + e.Error.Message); 
     } 

     else 
     { 
      this.progressRichTextBox.Text = "Done!"; 
     } 
    } 
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     this.progressRichTextBox.Text = (e.ProgressPercentage.ToString() + "%"); 
    } 
} 

而且继承人的ftp类:

public void upload(System.Windows.Forms.RichTextBox progressRichTextBox, string remoteFile, string localFile) 
    { 

     FileInfo fileInfo = new FileInfo(localFile); 
     /* Create an FTP Request */ 
     ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remoteFile); 
     /* Log in to the FTP Server with the User Name and Password Provided */ 
     ftpRequest.Credentials = new NetworkCredential(user, pass); 
     /* Specify generic group name for faster upload */ 
     ftpRequest.ConnectionGroupName = "AffiliateUpload"; 
     /* Specify the Type of FTP Request */ 
     ftpRequest.Method = WebRequestMethods.Ftp.UploadFile; 
     /* Server connection options */ 
     ftpRequest.UseBinary = true; 
     ftpRequest.UsePassive = true; 
     ftpRequest.KeepAlive = true; 
     ftpRequest.ContentLength = fileInfo.Length; 
     /* Buffer for the Data */ 
     byte[] buff = new byte[bufferSize]; 
     int contentLen; 
     /* Open a File Stream to Read the File for Upload */ 
     FileStream localFileStream = fileInfo.OpenRead(); 

     try 
     { 
      // Stream to which the file to be upload is written 
      ftpStream = ftpRequest.GetRequestStream(); 

      // Read from the file stream 2kb at a time 
      contentLen = localFileStream.Read(buff, 0, bufferSize); 

      // Till Stream content ends 
      while (contentLen != 0) 
      { 
       // Write Content from the file stream to the 
       // FTP Upload Stream 
       ftpStream.Write(buff, 0, contentLen); 
       contentLen = localFileStream.Read(buff, 0, bufferSize); 
      } 

      // Close the file stream and the Request Stream 
      ftpStream.Close(); 
      localFileStream.Close(); 
      ftpRequest = null; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Failed sending to " + host + "/" + remoteFile + " (" + ex.Message + ")"); 
     } 
    } 
+0

我想这里发生了什么是你想从后台线程(ftp类)调用主UI线程。你需要让ftp类调用委托方法ProgressChanged并更新这种方式 –

+0

看看[Invoke](http://msdn.microsoft.com/en-us/library/zyzhdc6b(v = vs.110) ).aspx) –

+0

我强烈建议您尝试使用任务,如果可以的话。即使您无法使用[BCL软件包](https://www.nuget.org/packages/Microsoft.Bcl/1.1.8)迁移到.Net 4.5,也可以使用它们。它支持比Backgroundworker使用的模型更清洁的进度模型。 [This](http://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-round-1.html)是他们之间非常好的比较。 – julealgon

回答

0

你不需要在你上传方法来更新progressRichTextBox。删除该参数。您需要将worker对象提供给您的上传方法,并在其上调用worker.ReportProgress

+0

谢谢解决我的一半问题,所以我可以返回现在完成的%。我的问题的后半部分是当我的catch类方法返回异常时,我需要返回服务器响应代码。在form1中,我确实有RunWorkerCompleted的逻辑,但我不确定如何将错误传递回来。如果成功完成,我会看到“完成!”消息,但我从来没有看到“错误:”消息。那件我错过了什么? – aantiix

+0

看看这篇文章。 http://stackoverflow.com/questions/5499657/setting-runworkercompleted-value –

+1

感谢您的回应。要返回一个字符串,我最终使用UserState而不是该链接上列出的内容。我有几个地方需要在我的DoWork中向我的用户界面返回一个值,所以我使用了Invoke。现在似乎都在工作。 – aantiix