【发布时间】:2012-11-19 19:20:40
【问题描述】:
注意以下代码来自asp.net。
如果我有下面的(写得不好)代码
AmazonS3 s3Client = Amazon.AWSClientFactory.CreateAmazonS3Client();
// ...
// details elided
// ...
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler((s, args) =>
{
s3Client.PutObject(titledRequest);
});
new Thread(() => worker.RunWorkerAsync()).Start();
垃圾收集器是否足够聪明,永远不会收集 s3Client 对象,直到后台工作人员完成它?
请注意,我在线程内启动后台工作程序只是为了修复在我直接启动后台工作程序时在 asp.net 中引发的恼人错误。
【问题讨论】:
-
没错。这就是 GC 的用途。直到线程丢失所有引用,s3client 将被保留!
-
你为什么要开始一个新线程只是为了运行
RunWorkerAsync()。这是一个异步方法开始;该方法的内容只是创建一个新线程,对其进行一些配置,然后启动它。无需在后台线程中执行此操作;你这样做会增加毫无意义的开销。您也不需要定义使用 lambdas 时使用的委托,您可以完全删除new DoWorkEventHandler;它将根据上下文进行暗示。 -
@Servy 感谢您提供关于不需要定义委托的提示。另一方面,当您启动 backgroundWorker 时,asp.net 会抛出这个令人难以置信的烦人错误。从四处寻找似乎不是一个简单的解决方法,所以我使用了这个俗气的解决方法。
-
@AdamRackis 你没有提到这是在 ASP 环境中。在这方面,
BackgroundWorker根本不是为在 ASP 环境中工作而设计的。它设计用于在 winform/WPF 类型的环境中工作。您应该直接在新线程中执行长时间运行的工作,而不使用BackgroundWorker或使用Task来启动新的长时间运行的任务。 -
@Servy - 我在问题末尾的注释中确实提到了它,但无论如何,在 asp.net 环境中,您是否说 GC 会以不同的方式工作,并且在上面的代码中,S3客户实际上可能会被处置?
标签: c# asp.net c#-4.0 garbage-collection