所以我正在尝试使用.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(记录器成员)和线程(用于记录器调用)。通常在QueueUserWorkItem()天,我认为这些需要作为状态对象的一部分传递给委托。关闭是否会让我失去帮助呢?
另一个问题是此例程所使用的类型实现了IDisposable,因此位于using语句中。所以如果我做的话......
using (var bl = new ThreadBL()) {
t = bl.ViewThread(threadId);
}
...我是否会在dispose()调用和TPL调用lambda之间创建一场竞赛?
目前我看到上下文将数据保存回我的数据库但没有记录 - 也没有例外。这可能是我配置的事情,但关于这段代码的一些感觉很奇怪。我不想在其他线程中有未处理的异常。欢迎任何意见!
答案 0 :(得分:0)
至于关于闭包的问题,是的,这正是关闭的问题。您不必担心传递状态,而是从任何外部上下文中捕获它并将其复制到编译器提供的类中,这也是定义闭包方法的位置。编译器在这里做了很多魔术,让你的生活变得简单。如果你想了解更多我强烈建议在深度中选择Jon Skeet的C#。关于闭包的章节实际上是available here。
至于您的具体实现,它不会主要用于您提到的确切问题:任务将在ViewThread
结束时安排,但在您的ThreadBL
实例被处置之前可能无法执行的。