C # Async Ping: не работает из Threading.Timer - PullRequest
1 голос
/ 11 января 2011

Я надеюсь объяснить правильно. Я работаю над проектом, который запускает более 6000 одновременных асинхронных пингов каждые X минут. Если я пытаюсь запустить компонент с помощью кнопки в форме окна, он работает. Но если вы начинаете с «Threading.Timer», у него есть проблемы. Иногда приложение застревает в ожидании ответов на пинги, а иногда выдает исключение NullReferenceException при обращении к переменной, которая не может быть нулевой. Но если выполняется из кнопки в форме запроса пользователя, все работает нормально.

Я надеюсь, что кто-то может мне помочь.

using System.Net.NetworkInformation;
using System.Threading;

Ответы [ 3 ]

4 голосов
/ 11 января 2011

На первый взгляд, я бы сказал, что вы вносите некоторые изменения в графический интерфейс вашего класса. В связи с тем, что все работает нормально при нажатии кнопки, ваша задача выполняется в потоке графического интерфейса и может получить доступ ко всему там без каких-либо проблем. Если вы передаете свою задачу в собственный поток, у вас нет прямого доступа к GUI.

Для решения этой проблемы вы можете заключить вызовы графического интерфейса в вызов (Begin)Invoke() (более подробную статью об этих различиях команд можно найти здесь ). Чтобы сделать это немного проще, вы также можете использовать один из следующих методов расширения:

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);
        }
    }
}

Использование будет:

myTextBox.InvokeIfRequired((ctrl) => ctrl.Text == "SomeNewText");
0 голосов
/ 15 января 2011

Спасибо всем за помощь!Я нашел решение (за время работы).Все, что я сделал, это изменил способ, которым вы уничтожаете объекты, «пингующие», чтобы получить ваш повтор.Теперь уничтожьте каждый объект «ping» в методе «PingResult», используя параметр «sender» (ссылка на ping) следующим образом:

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

Это работает для меня.Я надеюсь, что это поможет другим.

Приветствие и большое спасибо за все!

0 голосов
/ 13 января 2011

Вы пытались использовать несколько BackgroundWorker вместо Timer?

...