【问题标题】:What is the best approach to send some text from one class to another (with some restrictions)?将一些文本从一个类发送到另一个类(有一些限制)的最佳方法是什么?
【发布时间】:2009-02-14 17:12:06
【问题描述】:

我正在尝试在我的应用程序中实现日志查看器。这个想法很简单,一个显示从其他类发送的一些消息的列表框,但我不知道最好的方法是什么。

我最初的想法是制作一个包含 ListQueue 的 Logger 类(singletone),然后我将添加一个 方法 AddMessage(string s) 或类似的东西。当这个方法被调用时,它会将消息添加到列表或队列中,并且它会触发一个 NewMessage 事件。这个事件是因为我认为每隔一段时间检查一次列表不是一个好主意。消息序列可能是 3 个连续的,然后是 40 分钟没有任何消息,然后是更多...

所以,在我的表单类中(或任何我想接收消息的地方)我会听这个事件来清空列表或队列(这是因为即使列表框(最终受体)尚未创建)。列表的想法是在没有人监听事件时保存消息。

另外,我设置了 300 条消息的限制……所以每次我要添加新消息时,最旧的消息都会被删除……像这样:

while(listbox.Items.Count > 300)
{
    listbox.Items.RemoveAt(0);
}

你认为这是最好的方法吗?

感谢您的宝贵时间。 最好的问候。

编辑 1:我不想使用其他框架。

编辑 2:停止建议框架或其他应用程序。我想了解背后的逻辑,以及我所提议的是对还是错!

【问题讨论】:

  • 你的限制是愚蠢的。 Log4net 成熟且无风险。如果您编写自己的实现,您将浪费大量时间来完善和修复错误。您可能会引入同步问题。
  • 与其责备别人回答了你的实际问题,而不是责备你脑子里想的但表达不好的问题,你为什么不为浪费了试图帮助的人的时间而道歉你并重写你的问题以反映你真正想要的。
  • 如果你想学习,这不是一个愚蠢的限制。我想我在这里是为了讨论从一个班级向另一个班级发送消息的最佳方法......现在,我认为我对我想要的内容不够明确
  • @tvanfosson,你是对的,对不起

标签: c# .net logging


【解决方案1】:

需要考虑的一些问题是:

  • 您的应用程序是多线程的吗?写入消息的线程与读取消息并填充列表框的 UI 线程是否相同?

  • 每秒创建多少条消息?

  • 您希望每秒更新多少次列表框?

  • 一段时间内的最大消息数是多少?是全部显示在列表框中,还是丢弃旧的?

  • 是否要将消息也记录到文件中(例如,出于技术支持目的)?

  • 列表框(UI 元素)是唯一存储消息的地方吗?列表框是否始终显示,或者用户可以隐藏/销毁它?

  • 最终用户的复杂程度如何?您是否可以要求他们使用其他(更好的)工具来查看您的日志文件,或者您是否需要在您自己的 UI 中实现(相对简单的)查看器?

很抱歉用问题来回答您的问题,但这些问题需要先回答,然后您才能说“这是最好的方法吗?”。


它不是一个多线程应用程序,是一个我不想超载的小应用程序。

如果应用程序不是多线程的,那么“可能工作的最简单的事情”就是不要打扰列表或队列;而是让您的其他类直接将消息附加到 UI 列表框元素(可能通过委托),例如:

class MyClass
{
  Action<string> log;
  MyClass(Action<string> log)
  {
    this.log = log;
  }
  void Something()
  {
    //log a message
    log("Hello world!");
  }
}
class MyForm
{
  ListBox listBox = new ListBox();
  MyClass myClass;
  MyForm()
  {
    //create a delegate which logs strings
    //by writing them to the ListBox
    Action<string> log = delegate(string s) {
      listBox.Items.Add(s);
    };
    //pass this logger to classes which need to use it
    myClass = new MyClass(log);
    //test it
    myClass.Something();
  }
}

以下是使用非匿名委托的类似代码,具有您的一个 cmets 中要求的一些额外功能:

class MyForm
{
  ListBox listBox = new ListBox();
  MyClass myClass;
  MyForm()
  {
    //pass the Log action to classes which need to use it
    myClass = new MyClass(Log);
    //test it
    myClass.Something();
  }

  ///logs strings by writing them to the ListBox
  void Log(string s)
  {
    if (listBox.Items.Count == 300)
      listBox.Items.RemoveAt(0);
    listBox.Items.Add(s);
  }
}

我想我回答错了 (6)。即使尚未创建列表框,我也应该能够发送消息...这就是为什么我建议使用列表或队列

在这种情况下,您确实需要除了 ListBox 之外的存储空间。你的建议会奏效。另一种建议是:

  • 创建 ListBox 时,从 List 中填充它(使用 ListBox.Items.AddRange 方法)
  • 在Log函数中,如果ListBox不存在则将消息写入List,否则如果ListBox存在则将消息写入ListBox。

这样做可能比定义、侦听和触发事件(非常简单)简单。

【讨论】:

  • (1) 不是多头的 (2) 在一秒钟内可能是 5 条消息,然后是 40 分钟没有消息,然后是 1 ......但它们并不那么频繁 (3) 我是考虑仅在收到消息 (4) 300 时更新列表框,如果 listbox.items>300 我丢弃最旧的 (5) no
  • (6) 是的,它是唯一的地方,不能隐藏 (7) 如果他们想知道应用程序在做什么,只需要查看列表框,仅此而已。跨度>
  • 谢谢!,嗯..这似乎是我建议的更好选择,但我认为我回答错了(6)。即使尚未创建列表框,我也应该能够发送消息...这就是为什么我建议使用 List 或 Queue
  • 你最后的建议真好!非常感谢您的帮助
【解决方案2】:

有什么理由不使用现有技术?

  • Log4Net 或其他一些框架写入日志文件
  • 用于查看和过滤日志文件的文本编辑器(以及文本过滤器、grep 等)

编辑:我仍然很想使用 Log4Net 并为 some 类别/级别设置一个侦听器,该侦听器转储到滚动文本框。这样,您也可以将日志(可能更详细)记录到文件中。

编辑:如果您想学习,那么我建议您查看 Log4Net 的设计和实现。根据您的具体情况找出它的优势和劣势。

【讨论】:

  • 我觉得我表达的不好。我不想写日志文件,我想在我的应用程序中添加一个记录器......就像 ImgBurn 或 uTorrent 中的那个,一个向用户显示应用程序正在做什么的地方。抱歉,我的英文不好。
  • 那么您将重新发明轮子。为什么不利用其他人已经设计、编写和调试的东西?
  • 因为我想学习。我只是想知道我所建议的逻辑是否正确。
  • Jon,你知道tail -f 是如何实现的,即如何从其他人附加到的文本文件末尾读取新行吗?
  • @Chris - 我不知道,但开源的美妙之处在于你可以自己寻找。
【解决方案3】:

我想我和@Jon Skeet 一起讨论这个问题。使用现有的日志工具并将其与应用程序中的某种日志阅读器相结合。如果您使用 log4net,您可以登录到数据库并让您的日志视图定期轮询数据库以获取新消息。如果您登录到一个文件,您可以使用 FileSystemWatcher 来检测日志文件中的更改并重新加载您的视图。这将减少工作量,并且您可以相信通过依赖现有的、备受推崇的解决方案并对其进行扩展,该解决方案会更加健壮。

【讨论】:

    【解决方案4】:

    我将创建一个在程序的 main() 中定义的类。该类将包含一个允许日志可伸缩性的链表。然后,每当一个函数需要记录一些东西时,它就可以调用该类的一个运算符来记录一些东西。如果要使用线程,则需要小心互斥锁。

    编辑:

    您的想法是声明一个包含全局所有日志的类。因此,您创建了一个包含所有日志并能够显示它们的类。您将定义该类类型的变量并定义其他类,以便能够使用该全局类变量进行日志记录。

    【讨论】:

    • 你能提供一个简单的例子来说明你的建议吗?我不明白为什么它应该在程序的 main() 中。我也需要“记录”或发送来自其他类的消息。
    【解决方案5】:

    “因为我想学习。我只是想 知道我是什么的逻辑 建议好不好。”

    您最初概述的策略应该有效。我建议您继续进行设计,而不是继续这场辩论。您可能会在此过程中做出改变,但这将是一次学习体验,最终,您将拥有适合您的目标的东西。

    【讨论】:

      猜你喜欢
      • 2013-09-28
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2016-02-17
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      相关资源
      最近更新 更多