Получение C # BackgroundWorker процесса для вызова Pings

1

Прочитайте большинство (всех?) Ответов на вопросы о С# BackgroundWorker, но ни один из них не применим к этой ситуации. Если я пропустил один, пожалуйста, укажите мне в этом направлении!

Во всяком случае, у меня возникают проблемы с запуском процесса Ping в качестве фонового процесса. Я сделал простую форму для отправки писем и отправки отчетов. Это сработало хорошо, но это принесло бы результат только пользователю после того, как пинги были бы полными - таким образом, возникла необходимость в фоновом процессе. Я немного новичок в С# и не был знаком с особенностями BackgroundWorker. Однако нашел полезное пошаговое руководство от Microsoft здесь: http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx

Теперь я пытаюсь применить тот же процесс к объекту System.Net.NetworkInformation, а не к объекту System.IO.StreamReader. Я думаю, что я очень близко (читайте: я могу заставить приложение строить и запускать), но я постоянно получаю сообщение об ошибке во время выполнения (см. Ниже).

Это код Microsoft для своего примера приложения. Он работает как чемпион:

Метод в MainForm.cs, который вызывает класс Words.cs, упомянутый в пошаговом руководстве

void backgroundWorker1DoWork(object sender, DoWorkEventArgs e)
    {
        System.ComponentModel.BackgroundWorker worker;
        worker = (System.ComponentModel.BackgroundWorker)sender;
        Words WC = (Words)e.Argument;
        WC.CountWords(worker, e);
    }

Соответствующий метод в классе "Words.cs"

   public void CountWords(
        System.ComponentModel.BackgroundWorker worker,
        System.ComponentModel.DoWorkEventArgs e)
    {
        // Initialize the variables.
        CurrentState state = new CurrentState();
        string line = "";
        int elapsedTime = 20;
        DateTime lastReportDateTime = DateTime.Now;

        if (CompareString == null ||
            CompareString == System.String.Empty)
        {
            throw new Exception("CompareString not specified.");
        }
        // Open a new stream.        
        using (System.IO.StreamReader myStream = new System.IO.StreamReader(SourceFile))
        {
            // Process lines while there are lines remaining in the file. 
            while (!myStream.EndOfStream)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    line = myStream.ReadLine();
                    WordCount += CountInString(line, CompareString);
                    LinesCounted += 1;

                    // Raise an event so the form can monitor progress. 
                    int compare = DateTime.Compare(
                        DateTime.Now, lastReportDateTime.AddMilliseconds(elapsedTime));
                    if (compare > 0)
                    {
                        state.LinesCounted = LinesCounted;
                        state.WordsMatched = WordCount;
                        worker.ReportProgress(0, state);
                        lastReportDateTime = DateTime.Now;
                    }
                }
                // Uncomment for testing. 
                System.Threading.Thread.Sleep(5);
            }

            // Report the final count values.
            state.LinesCounted = LinesCounted;
            state.WordsMatched = WordCount;
            worker.ReportProgress(0, state);
        }
    }

Когда я пытаюсь выполнить подобный процесс (отправляя Ping вместо чтения файла), я получаю эту ошибку:

Error: Object reference not set to an instance of an object.
Details: System.Collections.ListDictionaryInternal //This is defined in the MyApp namespace as: using System.Collections
Source: MyApp
StackTrack:    at MyApp.MainForm.Bw01DoWork(Object sender, DoWorkEventArgs e) in
[path]\MainForm.cs:line 152
   at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
   at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
Target: Void Bw01DoWork(System.Object, System.ComponentModel.DoWorkEventArgs)

Вот мой метод. Строка 152, на которую ссылается ошибка, является самой последней строкой последнего метода в MainForm.cs (имена var разные, но вы получаете идею):

void Bw01DoWork(object sender, DoWorkEventArgs e)
    {
        System.ComponentModel.BackgroundWorker worker;
        worker = (System.ComponentModel.BackgroundWorker)sender;
        PTResults PR = (PTResults)e.Argument;
        PR.SendPings(worker, e);  // Line 152
    }

И соответствующая часть класса PTResults.cs:

using (Ping newPing = new Ping())
        {
            PingReply reply = newPing.Send([Target Site],[Timeout]);
            if(reply.Status == IPStatus.Success)
            {
                state.PingOK = true;
            }
            else if(reply.Status == IPStatus.TimedOut)
            {
                state.PingOK = false;
                state.PingUpdateState = " Timed Out";                   
            }
            else if(reply.Status != IPStatus.Success)
            {
                state.PingOK = false;
                state.PingUpdateState = " FAILED";                          
            }
            else
            {
                state.PingOK = false;
                state.PingUpdateState = " UNKNOWN";                     
            }
            worker.ReportProgress(0, state.PingOK);
        }

Я думаю, что компонент System.Net.NetworkInformation.Ping не может быть вызван так же, как и System.IO.StreamReader. Мысли?

Я сомневаюсь, что это имеет значение, но FWIW я кодирую в SharpDevelop в системе Windows 8.1.

  • 0
    Мне повезло, мой ответ помог?
  • 0
    Еще нет. Я возиться с PingAsync. Тем не менее, я все еще в недоумении, почему мой код не работает так, как написано (так как потоковая передача ввода-вывода работала так хорошо). Можно ли вообще использовать Ping таким образом, или PingAsync - единственный реальный вариант здесь?
Теги:
winforms
backgroundworker
sharpdevelop

1 ответ

0

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

http://msdn.microsoft.com/en-us/library/ms144961(v=vs.110).aspx

Ещё вопросы

Сообщество Overcoder
Наверх
Меню