C# 对WF控件的跨线程调用
我在SharpPcap图书馆工作。我有以下代码:C# 对WF控件的跨线程调用,c#,winforms,multithreading,C#,Winforms,Multithreading,我在SharpPcap图书馆工作。我有以下代码: private void button1_Click(object sender, EventArgs e) { LivePcapDevice device = deviceList[cbDeviceList.SelectedIndex]; device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
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,消息为“Control 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方法。有什么问题吗?
顺便说一句,对不起我的英语。我想
设备\u 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
);
}