开发者

C# Async Ping: not work from a Threading.Timer

开发者 https://www.devze.com 2023-02-03 09:03 出处:网络
I hope to explain properly. I\'m working on a project that runs more than 6000 simultaneous asynchronous pings every X minutes. If I try to run the component from a button on a windows form it works.

I hope to explain properly. I'm working on a project that runs more than 6000 simultaneous asynchronous pings every X minutes. If I try to run the component from a button on a windows form it works. But if you start from a "Threading.Timer" it has problems. Sometimes the application gets stuck waiting for answers to pings, and sometimes throws NullReferenceException exception when you access a variable that I can not be null. But if executed from a button on a user request form work fine.

I hope someone can help me.

using System.Net.NetworkInformation;
using S开发者_Go百科ystem.Threading;


At a first guess i would say you make some updates to the GUI within your class. Due to the fact that everything works fine on a button press your task runs within the GUI thread and can access everything there without any problems. If you outsource your task into its own thread you don't have direct access to the GUI.

To resolve this you can wrap the gui calls into an (Begin)Invoke() call (a more in-depth article about these commands differences can be found here). To make it a little easier you can also use one of these extension methods:

public static class ControlExtensions
{
    public static void InvokeIfRequired(this Control c, Action<Control> action)
    {
        if (c.InvokeRequired)
        {
            c.Invoke(new Action(() => action(c)));
        }
        else
        {
            action(c);
        }
    }

    public static void BeginInvokeIfRequired(this Control c, Action<Control> action)
    {
        if (c.InvokeRequired)
        {
            c.BeginInvoke(new Action(() => action(c)));
        }
        else
        {
            action(c);
        }
    }
}

The usage would be:

myTextBox.InvokeIfRequired((ctrl) => ctrl.Text == "SomeNewText");


Did you try using several BackgroundWorker instead of a Timer?

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


Thank all for your help! I found the solution (for the time worked). All I did was change the way you destroy the objects "ping" to have received your replay. Now destroy each object "ping" in the method "PingResult" using the parameter "sender" (reference to the ping) as follows:

((Ping)sender).PingCompleted -= PingResult;
((IDisposable)sender).Dispose();

This works for me. I hope it helps others.

A greeting and thank you very much for everything!

0

精彩评论

暂无评论...
验证码 换一张
取 消