Перекрестные вызовы к элементам управления WF - PullRequest
0 голосов
/ 18 сентября 2010

Я работаю с библиотекой SharpPcap. У меня есть следующий код:

private void button1_Click(object sender, EventArgs e)
    {
        LivePcapDevice device = deviceList[cbDeviceList.SelectedIndex];
        device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
        device.Open(DeviceMode.Promiscuous, 1000);
        device.StartCapture();
        btStop.Enabled = true;
        btStartCapture.Enabled = false;
    }

void device_OnPacketArrival(object sender, CaptureEventArgs e)
    {         
        dgvPacketInfo.Rows.Add(e.Packet.Data, e.Packet.Timeval,
                                e.Packet.LinkLayerType);          
    }

У меня возникло исключение: InvalidOperationException с сообщением: «Доступ к dgvPacketInfo элемента управления осуществляется из потока, отличного от потока, в котором он был создан» Я прочитал это . И переписать мой код так:

private delegate void GetPacketInfoCallback(CaptureEventArgs packet);

void device_OnPacketArrival(object sender, CaptureEventArgs e)
    {
        Thread newThread = new Thread(delegate()
                                          {
                                              GetPacketInfoCallback getPacketInfoCallback = new GetPacketInfoCallback(PrintIntoGridView);
                                              this.Invoke(getPacketInfoCallback, new object[] {e});
                                          });            
    }

private void PrintIntoGridView(CaptureEventArgs captureEventArgs)
    {
        dgvPacketInfo.Rows.Add("1", "2", "3"); // simple for test
        dgvPacketInfo.Rows.Add(captureEventArgs.Packet.Data, captureEventArgs.Packet.Timeval,
                               captureEventArgs.Packet.LinkLayerType);
    }

Но метод PrintIntoGridView не вызывается. В чем проблема? PS. Извините за мой английский.

1 Ответ

1 голос
/ 18 сентября 2010

Полагаю, device_OnPacketArrival уже выполняется в потоке, отличном от потока GUI, поэтому создание еще одного потока не потребуется. Попробуйте это:

void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
    if (InvokeRequired)
    {
        // If this is executing on a different thread than the GUI thread
        var getPacketInfoCallback = new GetPacketInfoCallback(PrintIntoGridView);
        Invoke(getPacketInfoCallback, new object[] { e });
    } 
    else 
    {
        // This is the GUI thread => 
        // you can safely modify GUI controls
        PrintIntoGridView(e);
    }
}

private void PrintIntoGridView(CaptureEventArgs captureEventArgs)
{
    dgvPacketInfo.Rows.Add("1", "2", "3"); // simple for test
    dgvPacketInfo.Rows.Add(
        captureEventArgs.Packet.Data, 
        captureEventArgs.Packet.Timeval,
        captureEventArgs.Packet.LinkLayerType
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...