Dowork完成后,背景工人runworkercompleted IS不被称为

发布于 2025-02-10 18:18:51 字数 2331 浏览 2 评论 0原文

我正在创建一个简单的程序,该程序ping我们网络上的所有服务器,并返回Ping请求是否成功。

我正在尝试使用背景工人,以便用户可以按ping按钮,而ping则在后台运行,而他们可以在UI

Dowork上执行其他操作,没有循环可以将其保留在那里,并且可以将其保留在那里,并且可以到达它行:

r = pinger.send(s)

,然后从我的理解中结束,因此应调用runworkCompletept的方法?

长时间的潜落后,我正在重新学习编程,所以如果我错过了一些明显的东西,我深表歉意 ...

   public Form1()
    {

        InitializeComponent();
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.WorkerSupportsCancellation = true;
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    }

    private void Ping_Btn_Click(object sender, EventArgs e)
    {

        count = Convert.ToInt32(pingSeconds_TxtBox.Text);

        if (backgroundWorker1.IsBusy != true)
        {
            // Start operation
            backgroundWorker1.RunWorkerAsync();
        }
       
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerSupportsCancellation = true;
    }

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

        if(worker.CancellationPending == true)
        {
            e.Cancel = true;
        }
        else
        {
            for(int i = 0; i <= count; i++)
            {
                MessageBox.Show("something is happening");
                // Create ping object
                Ping pinger = new Ping();
                PingReply r;
                // IP to test ping
                string s = "###";

                try
                {
                    r = pinger.Send(s);

                }
                catch (Exception b)
                {
                    MessageBox.Show(b.ToString());
                }
            }
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Show me something");

        if(e.Cancelled == true)
        {
            statusLbl1.Text = "Cancelled";
        } else if(e.Error != null)
        {
            statusLbl1.Text = "Error: " + e.Error.Message;
        } else
        {
            statusLbl1.Text = "YEEEEEEEET";
        }
    }

... ...

I'm creating a simple program that pings all the servers on our network and returns whether the ping requests were successful.

I'm trying to utilise background workers so that the user can press the ping button and the pings run in the background while they can do other things on the UI

DoWork runs fine, there's no loop to keep it there infinitely, and it reaches the line:

r = pinger.Send(s)

and then from my understanding it ends and so the RunWorkCompleted method should be called?

I'm relearning programming after a long abscense so if I missed something obvious I apologise
...

   public Form1()
    {

        InitializeComponent();
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.WorkerSupportsCancellation = true;
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    }

    private void Ping_Btn_Click(object sender, EventArgs e)
    {

        count = Convert.ToInt32(pingSeconds_TxtBox.Text);

        if (backgroundWorker1.IsBusy != true)
        {
            // Start operation
            backgroundWorker1.RunWorkerAsync();
        }
       
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerSupportsCancellation = true;
    }

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

        if(worker.CancellationPending == true)
        {
            e.Cancel = true;
        }
        else
        {
            for(int i = 0; i <= count; i++)
            {
                MessageBox.Show("something is happening");
                // Create ping object
                Ping pinger = new Ping();
                PingReply r;
                // IP to test ping
                string s = "###";

                try
                {
                    r = pinger.Send(s);

                }
                catch (Exception b)
                {
                    MessageBox.Show(b.ToString());
                }
            }
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Show me something");

        if(e.Cancelled == true)
        {
            statusLbl1.Text = "Cancelled";
        } else if(e.Error != null)
        {
            statusLbl1.Text = "Error: " + e.Error.Message;
        } else
        {
            statusLbl1.Text = "YEEEEEEEET";
        }
    }

...

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

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

发布评论

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

评论(3

(り薆情海 2025-02-17 18:18:51

您需要将backgroundWorker1_runworkercompleted事件处理程序附加到runworkerCompleted事件。 C#编译器不会根据命名约定将事件挂钩。您必须明确地进行。

public Form1()
{
    InitializeComponent();
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
}

You need to attach your backgroundWorker1_RunWorkerCompleted event handler to the RunWorkerCompleted event. The C# compiler doesn't hook handlers to events based on naming conventions. You have to do it explicitly.

public Form1()
{
    InitializeComponent();
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
}
热情消退 2025-02-17 18:18:51

我强烈建议您将此代码转换为使用async 等待,它在表示代码控制的流程方面要好得多,而不是使用旧的backgroundworker这基本上是贬低的。

注意以下注意:

  • 主事件处理程序应为async void,但所有其他异步功能都应为async Task
  • 使用Semaphoreslim.waitasync(0)检查我们是否忙。
  • ping对象需要或最后将其处置,concellationTokenSource也是如此。
  • &lt; = count看起来应该是&lt;计数因为您从0开始。
SemaphoreSlim sem = new SemaphoreSlim(1, 1);
CancellationToken token;

private async void Ping_Btn_Click(object sender, EventArgs e)
{
    if (!await sem.WaitAsync(0))
        return;

    var tokenSource = new CancellationTokenSource();
    try
    {
        var count = Convert.ToInt32(pingSeconds_TxtBox.Text);
        await RunPingsAsync(count, tokenSource.Token);
        statusLbl1.Text = "YEEEEEEEET";
    }
    catch (OperationCanceledException)
    {
        statusLbl1.Text = "Cancelled";
    }
    catch (Exception e)
    {
        statusLbl1.Text = "Error: " + e.Error.Message;
    }
    finally
    {
        sem.Release();
        tokenSource.Dispose();
    }
        
    MessageBox.Show("Show me something");
}

private Task RunPingsAsync(int count, CancellationToken token)
{
    for(int i = 0; i < count; i++)
    {
        token.ThrowIfCancellationRequested();

        MessageBox.Show("something is happening");
        // IP to test ping
        string s = "###";

        // Create ping object
        using (Ping pinger = new Ping())
        {
            var r = await pinger.SendPingAsync(s);
        }
    }
}

I strongly suggest you convert this code to use async await which is much better at representing the flow of code control, rather than using the old BackgroundWorker which is basically deprecated.

Note the following:

  • The main event handler should be async void but all other async functions should be async Task.
  • Use of SemaphoreSlim.WaitAsync(0) to check if we are busy.
  • Ping object needs a using or finally to dispose it, as does the CancellationTokenSource.
  • <= count looks like it should be < count because you begin at 0.
SemaphoreSlim sem = new SemaphoreSlim(1, 1);
CancellationToken token;

private async void Ping_Btn_Click(object sender, EventArgs e)
{
    if (!await sem.WaitAsync(0))
        return;

    var tokenSource = new CancellationTokenSource();
    try
    {
        var count = Convert.ToInt32(pingSeconds_TxtBox.Text);
        await RunPingsAsync(count, tokenSource.Token);
        statusLbl1.Text = "YEEEEEEEET";
    }
    catch (OperationCanceledException)
    {
        statusLbl1.Text = "Cancelled";
    }
    catch (Exception e)
    {
        statusLbl1.Text = "Error: " + e.Error.Message;
    }
    finally
    {
        sem.Release();
        tokenSource.Dispose();
    }
        
    MessageBox.Show("Show me something");
}

private Task RunPingsAsync(int count, CancellationToken token)
{
    for(int i = 0; i < count; i++)
    {
        token.ThrowIfCancellationRequested();

        MessageBox.Show("something is happening");
        // IP to test ping
        string s = "###";

        // Create ping object
        using (Ping pinger = new Ping())
        {
            var r = await pinger.SendPingAsync(s);
        }
    }
}
浪菊怪哟 2025-02-17 18:18:51

如果要保留无限循环,则必须在背景worker1_dowork方法中进行循环。 也这样的事情

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker) sender;
    while (!worker.CancellationPending)
    {
        //Do your stuff here
        for(int i = 0; i <= count; i++)
        {
            MessageBox.Show("something is happening");
            // Create ping object
            Ping pinger = new Ping();
            PingReply r;
            // IP to test ping
            string s = "###";

            try
            {
                r = pinger.Send(s);

            }
            catch (Exception b)
            {
                MessageBox.Show(b.ToString());
            }
        }
    }        
 }

也是一个好主意,从您的背景线程中显示消息框,将其记录在控制台或任何文件中。

If you want to keep an infinite loop, then you have to make a loop in your backgroundWorker1_DoWork Method. Something like this

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker) sender;
    while (!worker.CancellationPending)
    {
        //Do your stuff here
        for(int i = 0; i <= count; i++)
        {
            MessageBox.Show("something is happening");
            // Create ping object
            Ping pinger = new Ping();
            PingReply r;
            // IP to test ping
            string s = "###";

            try
            {
                r = pinger.Send(s);

            }
            catch (Exception b)
            {
                MessageBox.Show(b.ToString());
            }
        }
    }        
 }

Also, it is not a good idea to display message boxes from your background thread, Log it in console or any file.

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