微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.NET TPL lambda和闭包-此代码将起作用

如何解决.NET TPL lambda和闭包-此代码将起作用

| 因此,我试图在.NET 4.0中使用TPL功能,并使用如下代码(不要笑):
/// <summary>Fetches a thread along with its posts.  Increments the thread viewed counter.</summary>
public Thread ViewThread(int threadId)
{
   // Get the thread along with the posts
   Thread thread = this.Context.Threads.Include(t => t.Posts)
       .FirstOrDefault(t => t.ThreadID == threadId);

   // Increment viewed counter
   thread.NumViews++;
   Task.Factory.StartNew(() =>
   {
       try {
           this.Context.SaveChanges();
       }
       catch (Exception ex) {
           this.Logger.Error(\"Error viewing thread \" + thread.Title,ex);
       }

       this.Logger.DebugFormat(@\"Thread \"\"{0}\"\" viewed and incremented.\",thread.Title);
   });

   return thread;
}
因此,我对lambda的直接关注是this.Context(我的实体框架datacontext成员),this.Logger(logger成员)和线程(在logger调用中使用)。通常,在QueueUserWorkItem()天内,我认为这些将需要作为状态对象的一部分传递给委托。封闭会否使我不必这样做呢? 另一个问题是此例程所在的类型实现Idisposable,因此位于using语句中。所以,如果我做类似...
using (var bl = new ThreadBL()) {
            t = bl.ViewThread(threadId);
        }
...我是否要在dispose()调用和TPL调用我的lambda之间创建竞赛? 目前,我看到上下文将数据保存回我的数据库,但是没有日志记录-也不例外。就我而言,这可能是配置问题,但有关此代码的某些事情感觉很奇怪。我不想在其他线程中有未处理的异常。欢迎任何输入!     

解决方法

至于您对闭包的问题,​​是的,这正是闭包的含义。您不必担心传递状态,而是从任何外部上下文中为您捕获状态并将其复制到编译器提供的类中,该类也是定义闭包方法的地方。编译器在这里做了很多魔术,使您的生活变得简单。如果您想了解更多,我强烈建议您使用Depth的Jon Skeet的C#。实际上,这里有关于闭包的章节。 对于您的特定实现,它主要不适用于您提到的确切问题:Task将安排在
ViewThread
的末尾,但可能在处置
ThreadBL
实例之前不会执行。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。