如何将后台工作者与远程类一起使用

发布于 2024-08-14 18:49:13 字数 722 浏览 6 评论 0原文

如何将此类的 CountValue 更改报告给后台工作人员

class SomeOtherClass
{
    public void CountUp()
    {
        int CountValue;
        for (int i = 0; i < 100000000; i++)
            CountValue = i;
    }
}

这是 DoWork 函数的实现

   private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        SomeOtherClass MyOtherClass = new SomeOtherClass();
        int CountValue;
        if ((worker.CancellationPending == true))
        {
            e.Cancel = true;
        }
        else
        {
            MyOtherClass.CountUp();
            worker.ReportProgress(CountValue);
        }
    }

How do I report change of the CountValue from this class to a backgroundworker

class SomeOtherClass
{
    public void CountUp()
    {
        int CountValue;
        for (int i = 0; i < 100000000; i++)
            CountValue = i;
    }
}

Here is the implemetation of the DoWork function

   private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        SomeOtherClass MyOtherClass = new SomeOtherClass();
        int CountValue;
        if ((worker.CancellationPending == true))
        {
            e.Cancel = true;
        }
        else
        {
            MyOtherClass.CountUp();
            worker.ReportProgress(CountValue);
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千紇 2024-08-21 18:49:13

从 SomeOtherClass 现在看起来的方式来看,没有明显的方法。如果您可以更改 SomeOtherClass,则可以添加一个事件:

class CountEventArgs : EventArgs
{
    public int CountValue { get; private set; }
    public CountEventArgs (int countValue)
    {
        CountValue = countValue;
    }
}
class SomeOtherClass
{
    public event EventHandler<CountEventArgs> CountValueChanged;
    public void CountUp()
    {
        int CountValue;
        for (int i = 0; i < 100000000; i++)
        {
            CountValue = i;
            OnCountValueChanged(new CountEventArgs(CountValue));
        }
    }
    private void OnCountValueChanged(CountEventArgs e)
    {
        EventHandler<CountEventArgs> temp = CountValueChanged;
        if (temp != null)
        {
            temp(this, e);
        }
    }
}

然后您可以设置一个事件处理程序并使用 BackgroundWorker 的 ReportProgress 方法将信息转发到 UI:

BackgroundWorker worker = sender as BackgroundWorker;
SomeOtherClass MyOtherClass = new SomeOtherClass();
// set up an anonymous method as event handler for the CountValueChanged
// event. This event handler passes the count value on to the ReportProgress
// method of the background worker, which in turn will raise the ProgressChanged
// event on the UI thread.
MyOtherClass.CountValueChanged += (eventSender, eventArgs) =>
{
    worker.ReportProgress(eventArgs.CountValue);
};

MyOtherClass.CountUp();

In the way that SomeOtherClass looks now there is no obvious way. If you can change SomeOtherClass you could add an event:

class CountEventArgs : EventArgs
{
    public int CountValue { get; private set; }
    public CountEventArgs (int countValue)
    {
        CountValue = countValue;
    }
}
class SomeOtherClass
{
    public event EventHandler<CountEventArgs> CountValueChanged;
    public void CountUp()
    {
        int CountValue;
        for (int i = 0; i < 100000000; i++)
        {
            CountValue = i;
            OnCountValueChanged(new CountEventArgs(CountValue));
        }
    }
    private void OnCountValueChanged(CountEventArgs e)
    {
        EventHandler<CountEventArgs> temp = CountValueChanged;
        if (temp != null)
        {
            temp(this, e);
        }
    }
}

Then you can set up an event handler and use the ReportProgress method of the BackgroundWorker to relay the information to the UI:

BackgroundWorker worker = sender as BackgroundWorker;
SomeOtherClass MyOtherClass = new SomeOtherClass();
// set up an anonymous method as event handler for the CountValueChanged
// event. This event handler passes the count value on to the ReportProgress
// method of the background worker, which in turn will raise the ProgressChanged
// event on the UI thread.
MyOtherClass.CountValueChanged += (eventSender, eventArgs) =>
{
    worker.ReportProgress(eventArgs.CountValue);
};

MyOtherClass.CountUp();
空城仅有旧梦在 2024-08-21 18:49:13

您的代码中犯了很多错误。特别是,当您每秒向 Windows 发送数百万次新事件时,您不能指望 Windows 能够跟上。仅在完成大量工作后才尝试发送更新。此外,ReportProgress 的参数应该是百分比 (0 - 100)。如果要发送百分比以外的数据,请使用用户状态参数。以下是您可以使用的一些代码:

using System;
using System.Windows.Forms;
using System.ComponentModel;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker.RunWorkerAsync();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            backgroundWorker.CancelAsync();
        }

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

            int countValue = 0;
            int max = 100000000;
            for (int i = 0; i < max; i++)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                countValue = i;
                if (i % 1000000 == 0)
                    worker.ReportProgress(i / (max / 100), i);
            }
            worker.ReportProgress(100, max);
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            labelCounter.Text = ((int)e.UserState).ToString();
        }
    }
}

注意:请记住在设计器中将工作线程的 SupportsProgress 和 SupportsCancellation 设置为 true。

You have made a lot of errors in your code. In particular, you can't expect Windows to keep up when you are sending it a new event millions of times per second. Try only sending an update when you have completed a large block of work. Also, the parameter for ReportProgress should be a percentage (0 - 100). If you want to send data other than a percentage, use the user state parameter. Here is some code you can use:

using System;
using System.Windows.Forms;
using System.ComponentModel;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker.RunWorkerAsync();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            backgroundWorker.CancelAsync();
        }

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

            int countValue = 0;
            int max = 100000000;
            for (int i = 0; i < max; i++)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                countValue = i;
                if (i % 1000000 == 0)
                    worker.ReportProgress(i / (max / 100), i);
            }
            worker.ReportProgress(100, max);
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            labelCounter.Text = ((int)e.UserState).ToString();
        }
    }
}

Note: remember to set the worker's SupportsProgress and SupportsCancellation to true in the designer.

梅倚清风 2024-08-21 18:49:13

不确定我是否理解,但我会尝试一下。为什么不改变 CountUp() 返回值呢?

public int CountUp()    
{
    int CountValue;
    for (int i = 0; i < 100000000; i++)
        CountValue = i;    

    return CountValue;
}

这段代码的目的对我来说没有意义,所以我不确定我是否理解您想要完成的任务。

Not sure I understand but I'll give it a shot. Why not change CountUp() to return a value?

public int CountUp()    
{
    int CountValue;
    for (int i = 0; i < 100000000; i++)
        CountValue = i;    

    return CountValue;
}

The purpose of this code doesn't make sense to me so I'm not sure I understand what you were trying to accomplish.

荒岛晴空 2024-08-21 18:49:13

我认为您不了解局部变量的工作原理... CountUp 方法中的 CountValue 只会写入 CountUp 中的局部变量> 方法。它不会影响 backgroundWorker_DoWork 方法中的 CountUp 变量。您必须将 CountUp 移至 DoWork 方法才能使其正常工作。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    for (int i = 0; i < 100000000; i++)
    {
        if (worker.CancellationPending)
        {
            e.Cancel = true;
            break;
        }

        worker.ReportProgress(i);
    }
}

I don't think you understand how local variables work... the CountValue in your CountUp method will only write to the local variable in your CountUp method. It does not affect the CountUp variable in your backgroundWorker_DoWork method. You would have to move CountUp to the DoWork method for it to work.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    for (int i = 0; i < 100000000; i++)
    {
        if (worker.CancellationPending)
        {
            e.Cancel = true;
            break;
        }

        worker.ReportProgress(i);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文