【问题标题】:EventHandler fires thread only once instead of multiple times due to unhandled boundary case由于未处理的边界情况,EventHandler 仅触发线程一次而不是多次
【发布时间】:2016-06-02 15:39:35
【问题描述】:

我有一个监听刻度更新的事件,会被点击 100 次。

每点击 10 次,我就用另一种方法添加要采样的内容。然而,这个线程/方法只被调用一次,而不是 9 次。

我相信这可能是由于 tickList.RemoveRange(0,10) 在另外 10 个事件蜂拥而至之前没有被重置为 0...导致我的 If 案例 (tickList.Count == 10) 不再为真。

这里有一些关于我如何调用线程的问题,或者任何解释这种边界情况的方法。因此,将事件处理程序上的滴答数据保持在最低限度?

    private  static void OnTickUpdated(object source, TickEventArgs args)
    {
       Console.WriteLine(args.Close);
       tickList.Add(args.Close);

        if (tickList.Count == 10)
        {
            Console.WriteLine("We hit sample size");


            Thread runThread = new Thread(() =>
            {
                foreach (var data in tickList)
                {
                    Console.WriteLine("Sample set, do some work: "  + data);
                }

            });

            runThread.Start();
            if (runThread.ThreadState == ThreadState.Stopped)
            {
                tickList.RemoveRange(0, 10);
            }
        }
    }

【问题讨论】:

    标签: c# multithreading events


    【解决方案1】:

    首先,您的 TickList 是线程安全的吗?如果不是这样,您最终会得到并发更新,这可能会给您带来问题。

    我强烈建议使用更合适的机制,例如队列。然后,这遵循生产者/消费者模式。

    然后您可以改用if (ticklist.count >= 10),然后在队列仍在生成时弹出前 10 个项目。当您弹出时,您正在按预期减少队列大小,但仍然可以在不破坏程序流程的情况下加入更多队列。

    您需要确保不会一次对队列耗尽进行多次调用,可能是通过锁定方法。

    此外,将“10”作为常量或配置嵌入某处,因此如果您需要增加批次的大小,这样做非常简单且不易出现人为错误。

    在最后一次迭代之后,确保调用队列排空例程以确保它是空的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2014-08-11
      相关资源
      最近更新 更多