多线程中注册的事件仅执行一次?

KNET2010 2014-08-13 05:25:44

主要问题:
多线程中注册的事件为什么会只执行一次呢?我想让它每次满足条件时都执行。

具体描述:
有两个按钮,一个按钮是 btnStart ,主要用来开始执行事件 currentDevice_OnPcapStatistics ;另一个按钮 btnStop ,主要用来停止事件 currentDevice_OnPcapStatistics 的执行。

代码逻辑描述:
btnStart()事件:new 对象 -> 对象注册事件 currentDevice_OnPcapStatistics () -> 对象.Start() 使用线程 threadA 完成这些操作
btnStop()事件:Stop() -> 对象 = null -> 注销对象事件 currentDevice_OnPcapStatistics () -> 使用线程 threadA 完成这些操作 -> threadA.Abort() -> threadA = null

第一次点击 btnStart 时,事件 currentDevice_OnPcapStatistics () 能够执行,点击 btnStop后,再点击 btnStart,事件 currentDevice_OnPcapStatistics () 不会再执行了...求解~

贴关键代码:
btnStart()事件内的代码:

DelegateMethod dm3 = delegate()
{
var devices = CaptureDeviceList.Instance;

if (devices.Count > 0)
{
captureDeviceList = devices;

foreach (WinPcapDevice device in captureDeviceList)
{
if (device.Name.ToLower().EndsWith(adapterID.ToLower()))
{
currentDevice = device;

if (currentDevice != null)
{
currentDevice.OnPcapStatistics += new StatisticsModeEventHandler(currentDevice_OnPcapStatistics);

int readTimeoutMilliseconds = 1000;

currentDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);

currentDevice.StartCapture();

break;
}
}
}
}
};

if (threadStatistic == null)
{
threadStatistic = new Thread(new ThreadStart(dm3));
}

threadStatistic.Start();


btnStop()事件内的代码:

DelegateMethod dm2 = delegate()
{
if (currentDevice != null)
{
Thread.Sleep(2000);
currentDevice.StopCapture();
currentDevice.Close();
currentDevice.OnPcapStatistics -= currentDevice_OnPcapStatistics;
currentDevice = null;
}
};

threadStatistic = new Thread(new ThreadStart(dm2));
threadStatistic.Start();
Thread.Sleep(2000);
threadStatistic.Abort();
threadStatistic = null;


事件 currentDevice_OnPcapStatistics() :

private void currentDevice_OnPcapStatistics(object sender, StatisticsModeEventArgs e)
{
//代码省略...
//这个事件仅在第一次Start()后才执行,纳闷...
}


求解~


...全文
361 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
KNET2010 2014-08-30
  • 打赏
  • 举报
回复
引用 26 楼 abc2013abc123 的回复:
楼主,改下代码试试:

DelegateMethod dm2 = delegate()
{
    if (currentDevice != null)
    {
        Thread.Sleep(2000);
        currentDevice.StopCapture();
        currentDevice.Close();
        currentDevice.OnPcapStatistics -= currentDevice_OnPcapStatistics;
        currentDevice = null;
    }
};

//先终止这个进程。
threadStatistic.Abort();
threadStatistic = new Thread(new ThreadStart(dm2));
threadStatistic.Start();
Thread.Sleep(2000);
threadStatistic.Abort();
threadStatistic = null;
多谢~ 确实是这个问题...
abc2013abc123 2014-08-30
  • 打赏
  • 举报
回复
楼主,改下代码试试:

DelegateMethod dm2 = delegate()
{
    if (currentDevice != null)
    {
        Thread.Sleep(2000);
        currentDevice.StopCapture();
        currentDevice.Close();
        currentDevice.OnPcapStatistics -= currentDevice_OnPcapStatistics;
        currentDevice = null;
    }
};

//先终止这个进程。
threadStatistic.Abort();
threadStatistic = new Thread(new ThreadStart(dm2));
threadStatistic.Start();
Thread.Sleep(2000);
threadStatistic.Abort();
threadStatistic = null;
於黾 2014-08-14
  • 打赏
  • 举报
回复
引用 15 楼 download_a01 的回复:
[quote=引用 14 楼 Z65443344 的回复:] 既然主线程里调用委托,就是用主线程执行,那你还定义线程和委托干嘛,主线程直接执行方法不好么
那两个委托不是主线程里调用的,是另开的一个线程调用的...[/quote] 一个意思 如果在哪个线程调委托,就是在哪个线程执行 那还定义委托和线程干嘛,那个线程直接执行方法不就得了
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 14 楼 Z65443344 的回复:
既然主线程里调用委托,就是用主线程执行,那你还定义线程和委托干嘛,主线程直接执行方法不好么
那两个委托不是主线程里调用的,是另开的一个线程调用的...
於黾 2014-08-14
  • 打赏
  • 举报
回复
既然主线程里调用委托,就是用主线程执行,那你还定义线程和委托干嘛,主线程直接执行方法不好么
於黾 2014-08-14
  • 打赏
  • 举报
回复
你对委托的理解有误.照你这么说,委托里执行循环,应该阻塞主线程啊,把委托当线程运行还有任何意义?
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 11 楼 Z65443344 的回复:
你先在dm3里注册了事件,又在dm2里将事件取消了,然后又在dm3注册事件,就会出现这个问题. 我不知道为什么,可能是VS的BUG? 你就不能通知dm3,让它自己将事件注销么
虽然是在dm3中注册了事件,在dm2中取消了事件,但它们毕竟是委托啊,可是依然在同一个线程里呀,都是threadStatistic里执行的...
於黾 2014-08-14
  • 打赏
  • 举报
回复
你先在dm3里注册了事件,又在dm2里将事件取消了,然后又在dm3注册事件,就会出现这个问题. 我不知道为什么,可能是VS的BUG? 你就不能通知dm3,让它自己将事件注销么
於黾 2014-08-14
  • 打赏
  • 举报
回复
引用 9 楼 download_a01 的回复:
[quote=引用 6 楼 Z65443344 的回复:] 不要跨线程操作事件 +=和-=都放到同一个线程里去执行.
代码中 +=和-= 已经放到同一个事件里去执行了...[/quote] 你这明显+=在dm3执行,-=在dm2执行
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 6 楼 Z65443344 的回复:
不要跨线程操作事件 +=和-=都放到同一个线程里去执行.
代码中 +=和-= 已经放到同一个事件里去执行了...
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 5 楼 WM_JAWIN 的回复:
设置断点,跟踪调试,看是不是有执行事件绑定
我都调试过了,才提出的这个问题...
於黾 2014-08-14
  • 打赏
  • 举报
回复
昨天刚刚有人问过相似的问题 在按钮里让timer停止,而在线程里使timer启动,timer的回调函数不执行.
於黾 2014-08-14
  • 打赏
  • 举报
回复
不要跨线程操作事件 +=和-=都放到同一个线程里去执行.
WM_JAWIN 2014-08-14
  • 打赏
  • 举报
回复
设置断点,跟踪调试,看是不是有执行事件绑定
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 3 楼 WM_JAWIN 的回复:
看上去,没什么问题。楼主是只找一个adapterID 就可以了?估计是跟线程无关,你可以直接用主线程执行一下看是不是也一样 另外:你的foreach 应该先检查null,再判断Name属性。
可能是我问题描述的还是不太准确,我想表达的不是这样的,其他地方都没问题(测试均通过),就是那个事件不执行...
WM_JAWIN 2014-08-14
  • 打赏
  • 举报
回复
看上去,没什么问题。楼主是只找一个adapterID 就可以了?估计是跟线程无关,你可以直接用主线程执行一下看是不是也一样 另外:你的foreach 应该先检查null,再判断Name属性。
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 1 楼 lyj224170707 的回复:
就代码来看是没问题。。 关键在于currentDevice.OnPcapStatistics这个事件的定义。。 也许你第一次点击开始、然后停止后做了什么。导致下次再点开始后OnPcapStatistics事件一直没有执行
我把代码都贴在上面了,做的操作就只有这些...
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 24 楼 Z65443344 的回复:
http://bbs.csdn.net/topics/390858564 你可以看看这个帖子 也可以写代码测试 在别的线程操作事件,会不执行的
嗯啊,我看到了,我也说了下我的想法...
於黾 2014-08-14
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390858564 你可以看看这个帖子 也可以写代码测试 在别的线程操作事件,会不执行的
KNET2010 2014-08-14
  • 打赏
  • 举报
回复
引用 22 楼 Z65443344 的回复:
所以给了你3个链接,让你看看委托操作UI应该怎么用.在第三个链接里. 你直接使用委托,那还是用线程去操作UI啊 你需要使用invork方法,让主线程去调用委托
喔喔,你是这个意思呀,我觉得问题的原因可能不是因为这个地方...
加载更多回复(7)

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧