C# BackgroundWorker ProgressChanged的表单是从单独的类触发的

C# BackgroundWorker ProgressChanged的表单是从单独的类触发的,c#,class,backgroundworker,C#,Class,Backgroundworker,我是C#新手,我正试图将我的思想集中在面向对象编程上。以下是我试图实现的目标: 我有一个带有Form1的Windows窗体应用程序和一个名为connect(相同名称空间)的单独类 我知道在执行大量代码时使用backgroundworkers是一种很好的做法(以免冻结UI)。所以我在Form1中创建了一个后台工作程序和一个progresschanged句柄。我试图找到如何在单独的connect类中触发progresschange。在Form1的progresschange块中,我有一个大小写/开关

我是C#新手,我正试图将我的思想集中在面向对象编程上。以下是我试图实现的目标:

我有一个带有Form1的Windows窗体应用程序和一个名为connect(相同名称空间)的单独类

我知道在执行大量代码时使用backgroundworkers是一种很好的做法(以免冻结UI)。所以我在Form1中创建了一个后台工作程序和一个progresschanged句柄。我试图找到如何在单独的connect类中触发progresschange。在Form1的progresschange块中,我有一个大小写/开关,用于确定屏幕上显示的文本


最好的方法是什么?要我将backgroundworker传递给另一个类吗?

您可以将connect类的步骤分解为单独的方法,并按如下顺序调用它们。您不必从connect类对象触发progresschanged事件

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
     ConnectClass conObject= new ConnectClass();
     backgroundWorker.ReportProgress(30, "Connecting ...");
     conObject.Connect();
     backgroundWorker.ReportProgress(30, "Connected."+"\n Executing query");
     conObject.Execute();
     backgroundWorker.ReportProgress(40, "Execution completed.");
}

您可以将connect类的步骤分解为单独的方法,并按如下顺序调用它们。您不必从connect类对象触发progresschanged事件

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
     ConnectClass conObject= new ConnectClass();
     backgroundWorker.ReportProgress(30, "Connecting ...");
     conObject.Connect();
     backgroundWorker.ReportProgress(30, "Connected."+"\n Executing query");
     conObject.Execute();
     backgroundWorker.ReportProgress(40, "Execution completed.");
}

您还可以将BackgroundWorker放在Connect类中。在这个类中,您可以创建事件来向调用表单报告进度和完成情况

using System;
using System.ComponentModel;

namespace WindowsTest
{
public class Connect
{
    BackgroundWorker bw;
    public Connect()
    {
        bw = new BackgroundWorker();
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    }

    public delegate void ProgressChangedHandler(Object sender, ProgressChangedEventArgs e);
    public event ProgressChangedEventHandler ProgressChanged;
    protected void RaiseProgressChangedEvent(ProgressChangedEventArgs e)
    {
        if (ProgressChanged == null)
        {
            return;
        }
        ProgressChanged(this, e);
    }

    public delegate void WorkCompleteEventHandler(Object sender, RunWorkerCompletedEventArgs e);
    public event WorkCompleteEventHandler WorkComplete;
    protected void RaiseWorkCompleteEvent(RunWorkerCompletedEventArgs e)
    {
        if (WorkComplete == null)
        {
            return;
        }
        WorkComplete(this, e);
    }

    public void Cancel()
    {
        if (bw.IsBusy)
        {
            bw.CancelAsync();            
        }
    }

    public void BeginLongRunningProcess()
    {
        bw.RunWorkerAsync();
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        RaiseWorkCompleteEvent(e);
    }

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        RaiseProgressChangedEvent(e);
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        if (ConnectToServer())
        {
            bw.ReportProgress(0, "Connected to server");
            e.Result = LongRunningProcess();
            if (e.Result.ToString() == "Cancelled")
            {
                e.Cancel = true;
                return;
            }
        }
        else
        {
            //Connection failed
            e.Cancel = true;    
        }
    }

    private bool ConnectToServer()
    { 
        //Attempt connection
        return true;
    }

    private string LongRunningProcess()
    {
        int recordCount = 250;
        for (int i = 0; i <= recordCount; i++)
        {
            if (bw.CancellationPending)
            {
                return "Cancelled";
            }
            double progress = ((double)i / (double)recordCount) * 100;
            bw.ReportProgress((int)progress , "Running Process");
            System.Threading.Thread.Sleep(25);
        }
        return "The result is 2";
    }
}
}
请注意,BackgroundWorker.ReportProgress()方法的第二个参数(UserState)可以传递任何对象。它不必是字符串。例如,如果从数据库检索到一行或多行,则可以通过此方法将该行传递回用户界面。BackgroundWorker.DoWork方法的e.结果也是如此


Eric

您还可以将BackgroundWorker放在Connect类中。在这个类中,您可以创建事件来向调用表单报告进度和完成情况

using System;
using System.ComponentModel;

namespace WindowsTest
{
public class Connect
{
    BackgroundWorker bw;
    public Connect()
    {
        bw = new BackgroundWorker();
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    }

    public delegate void ProgressChangedHandler(Object sender, ProgressChangedEventArgs e);
    public event ProgressChangedEventHandler ProgressChanged;
    protected void RaiseProgressChangedEvent(ProgressChangedEventArgs e)
    {
        if (ProgressChanged == null)
        {
            return;
        }
        ProgressChanged(this, e);
    }

    public delegate void WorkCompleteEventHandler(Object sender, RunWorkerCompletedEventArgs e);
    public event WorkCompleteEventHandler WorkComplete;
    protected void RaiseWorkCompleteEvent(RunWorkerCompletedEventArgs e)
    {
        if (WorkComplete == null)
        {
            return;
        }
        WorkComplete(this, e);
    }

    public void Cancel()
    {
        if (bw.IsBusy)
        {
            bw.CancelAsync();            
        }
    }

    public void BeginLongRunningProcess()
    {
        bw.RunWorkerAsync();
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        RaiseWorkCompleteEvent(e);
    }

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        RaiseProgressChangedEvent(e);
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        if (ConnectToServer())
        {
            bw.ReportProgress(0, "Connected to server");
            e.Result = LongRunningProcess();
            if (e.Result.ToString() == "Cancelled")
            {
                e.Cancel = true;
                return;
            }
        }
        else
        {
            //Connection failed
            e.Cancel = true;    
        }
    }

    private bool ConnectToServer()
    { 
        //Attempt connection
        return true;
    }

    private string LongRunningProcess()
    {
        int recordCount = 250;
        for (int i = 0; i <= recordCount; i++)
        {
            if (bw.CancellationPending)
            {
                return "Cancelled";
            }
            double progress = ((double)i / (double)recordCount) * 100;
            bw.ReportProgress((int)progress , "Running Process");
            System.Threading.Thread.Sleep(25);
        }
        return "The result is 2";
    }
}
}
请注意,BackgroundWorker.ReportProgress()方法的第二个参数(UserState)可以传递任何对象。它不必是字符串。例如,如果从数据库检索到一行或多行,则可以通过此方法将该行传递回用户界面。BackgroundWorker.DoWork方法的e.结果也是如此


Eric

为什么要在connect类上处理更改的进度?connect类执行两项操作,例如连接到sql server,运行一两个查询。我希望能够最终更改form1上的statusstrip标签,以反映当前正在发生的事情(例如显示连接到服务器、运行查询等)。如果我可以用另一种不会锁定UI的方法从connect类更新form1上的statusstrip标签,我完全赞成。为什么要在connect类上处理更改的进度?connect类运行两种操作,例如连接到sql server、运行一两个查询。我希望能够最终更改form1上的statusstrip标签,以反映当前正在发生的事情(例如显示连接到服务器、运行查询等)。如果我可以用另一个不会锁定UI的方法从connect类更新form1上的statusstrip标签,我完全赞成。ReportProgress int参数每次都必须是不同的值吗?我看到第一个和第二个具有相同的int-backgroundworker是否认识到有更改,因为它刚刚被再次调用?int表示完成的工作百分比。所有TAK的总和应为100。并且progresschanged事件将由ReportProgress调用触发。您必须捕获消息已通过ReportProgress call in progress_changed事件,并相应地更新状态栏上的消息ReportProgress int参数是否每次都必须为不同的值?我看到第一个和第二个具有相同的int-backgroundworker是否认识到有更改,因为它刚刚被再次调用?int表示完成的工作百分比。所有TAK的总和应为100。并且progresschanged事件将由ReportProgress调用触发。您必须捕获消息已通过ReportProgress call in progress\u changed事件,并相应更新状态为barThank you!的消息!我也会看看这个谢谢!我也会看看这个