2014-05-23 2 views
1

이 문제를 해결하는 방법에 대한 포럼을 검색하고 읽는 서클에 참여할 것입니다. 노력의 하루 후에 나는 내 문제를 해결하는 방법을 잃어 버렸습니다. 파일을 업로드 할 때 텍스트 상자에 %를 반환해야합니다. 나는 업로드 부분에 문제가 없으며 동일한 클래스 내에 모든 코드를 포함하면 BackgroundWorker를 사용하여 값을 반환하는 데 문제가 없습니다. 그러나, 내가하고있는 일은 form1에서 ftp 클래스를 호출하는 것입니다. 내 UI에 표시 할 수 있고 내 FTP 클래스에서 반환 된 서버 응답 코드를 form1에 표시 할 수 있도록 form1에 백분율을 반환하는 ftp 클래스가 필요합니다. 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() + "%"); 
    } 
} 

그리고을 heres 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/ko-kr/library/zyzhdc6b(v=vs.110))를 살펴보십시오.) .aspx) –

+0

가능한 경우 할 일 목록을 시도해보십시오. [BCL 패키지] (https://www.nuget.org/packages/Microsoft.Bcl/1.1.8)를 사용하여 .Net 4.5로 마이그레이션 할 수없는 경우에도 사용할 수 있습니다. Backgroundworker에서 사용하는 것보다 훨씬 더 진보 된 진행 모델을 지원합니다. [이] (http://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-round-1.html)은 이들을 비교할 때 매우 좋습니다. – julealgon

답변

0

당신은 당신의 업로드 방법에 progressRichTextBox를 업데이트 할 필요가 없습니다. 해당 매개 변수를 제거하십시오. 업로드 방법에 worker 개체를 제공하고 worker.ReportProgress을 호출해야합니다.

+0

내 문제의 절반을 해결해 주셔서 감사합니다. 지금 완료했습니다. 후자의 문제는 ftp 클래스의 catch 메서드처럼 예외가 반환 될 때 서버 응답 코드를 반환해야한다는 것입니다. form1에는 RunWorkerCompleted에 대한 논리가 있지만 오류가 발생하면 다시 전달하는 방법을 모르겠습니다. 성공적으로 완료되면 "완료!" 메시지가 표시되지만 "오류 :"메시지가 표시되지 않습니다. 나는 그 조각에 대해 무엇을 놓치고 있습니까? – aantiix

+0

이 게시물을 확인하십시오. http://stackoverflow.com/questions/5499657/setting-runworkercompleted-value –

+1

응답 해 주셔서 감사합니다. 문자열을 반환하려면 해당 링크에 나열된 것 대신 UserState를 사용하여 종료해야합니다. DoWork의 중간에서 UI에 값을 반환해야하는 곳에 두 곳이있어서 Invoke를 사용했습니다. 모두 지금 일하고있는 것 같습니다. – aantiix

관련 문제