【问题标题】:Using Action with Task - not sure how it works将动作与任务一起使用 - 不确定它是如何工作的
【发布时间】:2012-08-15 16:57:32
【问题描述】:

我需要为我的应用程序创建一个单独的线程来记录一些事情,并且有人建议我使用 Task。

我似乎没有这个权利,因为我不完全理解任务(我猜)。

这是我所拥有的:

public static void LogException(string message, Exception ex)
{
  Action action= delegate() { logException(message, ex); };
  new Task(action);
}

public static void logException(string message, Exception ex)
{
  var stackTrace = new StackTrace();
  var origin = stackTrace.GetFrame(1).GetMethod().Name;
  var originclass = stackTrace.GetFrame(1).GetMethod().ReflectedType.Name;
  var neworigin = string.Format("{0}.{1}", originclass, origin);

  message += Environment.NewLine + Environment.NewLine + GetFullExceptionMessage(ex);

  if (string.IsNullOrEmpty(message)) message = "No message given";

  //var exceptions = GetAllErrMessages(ex);
  //message = exceptions.Aggregate(message, (current, exception) => current + Environment.NewLine + exception);

  EventLogging.LogEvent(neworigin, message, EventLogEntryType.Error, 9999);

  EmailMessage(neworigin, message, EventLogEntryType.Error);
}

我做错了什么?我没有收到任何错误,但话又说回来,我没有收到任何日志。

谢谢!

【问题讨论】:

    标签: c# delegates action task


    【解决方案1】:

    new Task(action); 创建了一个新任务,但它并没有做任何会导致它实际被执行的事情。

    在这种情况下,您可能只需使用:

    Task.Factory.StartNew( () => { /* code goes here */ });
    

    值得一提的是,如果您的代码特别短,那么创建/调度任务的开销可能比实际直接运行它要慢(这当然取决于该代码是什么)。还要确保在多线程环境中记录事件时,您的错误记录能够正常工作。如果没有,您可以决定不打扰,或者添加显式锁定。

    【讨论】:

    • 太棒了!那行得通。此外,在提到开销时,事件记录和/或电子邮件不是更多的开销吗?我怎么会知道?感谢您的帮助!
    • @ErocM 好吧,就我所知,LogEvent 方法只是将字符串存储在一个列表中,或者它已经创建了自己的线程来在后台进行日志记录。此外,如果它只是将 a 写入文件,这要归功于缓冲/缓存/等。这并不总是那么慢。要真正知道,您可能想淘汰您信任的StopWatch,看看哪个需要更长的时间(平均而言,经过大量迭代)才能运行。
    • 这就是我所做的。再次感谢您的帮助!
    【解决方案2】:

    new Task(action); 替换为Task.Factory.StartNew(action); 以在单独的线程上开始执行。

    【讨论】:

      【解决方案3】:

      像这样重写你的动作定义:

      Action action = new Action(delegate {
          logException(message, ex);
      });
      

      然后以action为参数创建一个新任务:

      Task myTask = new Task(action);
      

      现在你可以开始任务了:

      myTask.Start()
      

      你也可以直接调用Invokemethod来执行动作:

      action.Invoke()
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多