gpt4 book ai didi

C# SharpPcap 跨线程操作无效

转载 作者:太空宇宙 更新时间:2023-11-03 18:18:31 25 4
gpt4 key购买 nike

您好,我正在尝试将 SharpPcap 新版本 SharpPcap-2.2.0rc1.src 中示例 3 中的数据包捕获从控制台应用程序转换为 Windows 窗体应用程序。

当我尝试将已捕获的数据包添加到 ListView 控件时,我遇到了一个问题,我将收到一个错误:

(Cross-thread operation not valid: Control 'listViewPackets' accessed from a thread other than the thread it was created on.)

在这一行:
listViewPackets.Items.Add(e.Packet.ToString());

有什么解决这个问题的建议吗???

这是我的代码:

using SharpPcap;

namespace Packets
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}



// Retrieve the device list

private void btnLiDevicest_Click(object sender, EventArgs e)
{
var devices = LivePcapDeviceList.Instance;
// If no devices were found print an error
if (devices.Count < 1)
{
MessageBox.Show("No devices were found on this machine");
return;
}


int i = 0;

// Print out the devices
foreach (LivePcapDevice dev in devices)
{

///* Description */
//Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
cmbListDevice.Items.Add(dev.Name + " " + dev.Description);
i++;
}
LivePcapDevice device = devices[1];
// Register our handler function to the 'packet arrival' event
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);

// Open the device for capturing
int readTimeoutMilliseconds = 1000;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
device.StartCapture();


}


//Console.WriteLine();
//Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...",
// device.Description);
/// <summary>
/// Prints the time and length of each received packet
/// </summary>
///

protected void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
DateTime time = e.Packet.PcapHeader.Date;
uint len = e.Packet.PcapHeader.PacketLength;
//Console.WriteLine("{0}:{1}:{2},{3} Len={4}",
// time.Hour, time.Minute, time.Second, time.Millisecond, len);

// Console.WriteLine(e.Packet.ToString());

listViewPackets.Items.Add(e.Packet.ToString());


}



}


}

.....................................................................这是原始代码:

using System;
using System.Collections.Generic;
using SharpPcap;
namespace SharpPcap.Test.Example3
{
/// <summary>
/// Basic capture example
/// </summary>
public class BasicCap
{
public static void Main(string[] args)
{
// Print SharpPcap version
string ver = SharpPcap.Version.VersionString;
Console.WriteLine("SharpPcap {0}, Example3.BasicCap.cs", ver);

// Retrieve the device list
var devices = LivePcapDeviceList.Instance;

// If no devices were found print an error
if(devices.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}

Console.WriteLine();
Console.WriteLine("The following devices are available on this machine:");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();

int i = 0;

// Print out the devices
foreach(LivePcapDevice dev in devices)
{
/* Description */
Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
i++;
}

Console.WriteLine();
Console.Write("-- Please choose a device to capture: ");
i = int.Parse( Console.ReadLine() );

LivePcapDevice device = devices[i];

// Register our handler function to the 'packet arrival' event
device.OnPacketArrival +=
new PacketArrivalEventHandler( device_OnPacketArrival );

// Open the device for capturing
int readTimeoutMilliseconds = 1000;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);

Console.WriteLine();
Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...",
device.Description);

// Start the capturing process
device.StartCapture();

// Wait for 'Enter' from the user.
Console.ReadLine();

// Stop the capturing process
device.StopCapture();

Console.WriteLine("-- Capture stopped.");

// Print out the device statistics
Console.WriteLine(device.Statistics().ToString());

// Close the pcap device
device.Close();
}

/// <summary>
/// Prints the time and length of each received packet
/// </summary>
private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
DateTime time = e.Packet.PcapHeader.Date;
uint len = e.Packet.PcapHeader.PacketLength;
Console.WriteLine("{0}:{1}:{2},{3} Len={4}",
time.Hour, time.Minute, time.Second, time.Millisecond, len);
Console.WriteLine(e.Packet.ToString());
}
}
}

最佳答案

从另一个线程调用控件时:

if (listView1.InvokeRequired)
{
listView1.BeginInvoke(new MethodInvoker(
() => /*whatever you want with listview */));
}
else
{
/* whatever you want with listview */
}

如果您确定它总是在另一个线程上,那么只需忘记 if/else 并使用调用。

编辑:

所以在你的情况下,它看起来像:

if(listView1.InvokeRequired)
{
listView1.BeginInvoke(new MethodInvoker(
() => listViewPackets.Items.Add(e.Packet.ToString()) ));
}
else
{
listViewPackets.Items.Add(e.Packet.ToString());
}

(再次,或者只是 BeginInvoke 调用,如果它总是在不同的线程上运行)

编辑 2您会注意到 Shane 使用 Invoke 而我使用 BeginInvoke。我把它当作一种习惯的力量。使用 Invoke 将阻塞 UI 线程,如果您执行的操作需要更长的时间,则使用 BeginInvoke 会异步执行对 UI 的更新。

关于C# SharpPcap 跨线程操作无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2247427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com