简体   繁体   中英

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

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 System.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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM