Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BackgroundWorker报告来自不同类的进度_C#_Winforms_Ftp_Backgroundworker - Fatal编程技术网

C# BackgroundWorker报告来自不同类的进度

C# BackgroundWorker报告来自不同类的进度,c#,winforms,ftp,backgroundworker,C#,Winforms,Ftp,Backgroundworker,我会在圈子里搜索和阅读关于如何解决这个问题的论坛。经过一天的努力,我仍然不知道如何解决我的问题。我正在上载一个文件,需要在文本框中返回%。如果我将所有代码都包含在同一个类中,那么上传部分没有问题,使用BackgroundWorker返回值也没有问题。然而,我正在做的是从form1调用一个ftp类。我需要ftp类将百分比返回到form1,这样我就可以在UI中显示,还需要将ftp类返回的服务器响应代码显示在form1中。在我尝试在BackgroundWorker进程中运行此操作之前,一切都正常,当然

我会在圈子里搜索和阅读关于如何解决这个问题的论坛。经过一天的努力,我仍然不知道如何解决我的问题。我正在上载一个文件,需要在文本框中返回%。如果我将所有代码都包含在同一个类中,那么上传部分没有问题,使用BackgroundWorker返回值也没有问题。然而,我正在做的是从form1调用一个ftp类。我需要ftp类将百分比返回到form1,这样我就可以在UI中显示,还需要将ftp类返回的服务器响应代码显示在form1中。在我尝试在BackgroundWorker进程中运行此操作之前,一切都正常,当然,UI会变得无响应,并在上载完成后返回所有状态消息。这是我现在的代码。如何从ftp类中获取百分比并将其传递回form1,以及完成后的服务器响应代码

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

您不需要在上载方法中更新
progressRichTextBox
。删除该参数。您需要为上载方法提供
worker
对象,并在其上调用
worker.ReportProgress

我认为这里发生的事情是您试图从后台线程(ftp类)调用主UI线程。您需要更改ftp类调用委托方法ProgressChanged并更新该方法的进度查看我强烈建议您尝试使用任务(如果可以)。即使无法使用迁移到.Net 4.5,也可以使用它们。它支持比Backgroundworker使用的更干净的进度模型。两者之间的比较非常好。我使用的是.NET 3.5,因此BCL软件包目前还不是我的选择。感谢它解决了我一半的问题,因此我现在可以返回已完成的百分比。我的问题的后半部分是,当返回异常时,我需要返回服务器响应代码,就像在ftp类的catch方法中一样。在表格1中,我确实有RunWorkerCompleted的逻辑,但我不确定如何在出现错误时传递任何信息。如果成功完成,我会看到“完成!”消息,但我从未看到“错误:”消息。那篇文章我遗漏了什么?看看这篇文章。谢谢你的回复。为了返回一个字符串,我最终使用了UserState,而不是该链接上列出的内容。我有几个地方我需要返回一个值到我的UI在我的DoWork中间,所以我使用了调用。现在一切似乎都在运转。