我有一个Web服务方法FetchNumber(),其获取来自数据库的数,然后返回给调用者。但在它将号码返回给调用者之前,它需要将此号码发送到另一个服务,以便实例化并运行BackgroundWorker,其工作是将此号码发送到另一个服务。Web服务进行异步调用
public class FetchingNumberService : System.Web.Services.WebService
{
[WebMethod]
public int FetchNumber()
{
int value = Database.GetNumber();
AsyncUpdateNumber async = new AsyncUpdateNumber(value);
return value;
}
}
public class AsyncUpdateNumber
{
public AsyncUpdateNumber(int number)
{
sendingNumber = number;
worker = new BackgroundWorker();
worker.DoWork += asynchronousCall;
worker.RunWorkerAsync();
}
private void asynchronousCall(object sender, DoWorkEventArgs e)
{
// Sending a number to a service (which is Synchronous) here
}
private int sendingNumber;
private BackgroundWorker worker;
}
我不想阻止Web服务(FetchNumber())在发送这个号码到另一个服务,因为它需要很长的时间,主叫方不会关心发送的数量到另一个服务。来电者希望这个尽快返回。
FetchNumber()使得后台工作,并运行它,然后完成(而工人在后台线程中运行)。我不需要任何进度报告或后台工作人员的返回值。这更多是一个难忘的概念。
我的问题是这样的。由于Web服务对象是每个方法调用实例化的,当被调用的方法(在这种情况下为FetchNumber())完成时会发生什么,而它安装并运行的后台工作器仍在运行?
会发生什么事到后台线程? GC何时收集服务对象?这是否会阻止后台线程正确执行到最后?后台线程有没有其他副作用?
感谢任何输入。
如果BackgroundWorker只是AsyncUpdateNumber的构造函数的方法范围的局部变量,而不是其字段?对我来说,重要的问题不仅是这些对象是否会被收集,而且即使起始线程没有引用后台工作线程,线程是否会完成其工作? – 2010-05-31 20:39:50
当您在AsyncUpdateNumber类的构造函数中启动worker时,该方法将完成。但是,由于所有调用都会创建永远不会收集的新对象,因此会创建内存泄漏。如果*有*使用BackgroundWorker,只要Worker已经启动,您应该立即从BackgroundWorker注销事件实例。方法完成后,将BackgroundWorker设置为null。不过,我认为这是漫长的...看样品和简单。 – AxelEckenberger 2010-05-31 20:54:14
我不能这样做,因为我需要把作业的异步部分分成一个类(用于可重用性问题)。我可能会把你的样本放入一个班级,但这也让我面对原始问题。由于第一个线程只创建一个Async类的实例作为局部变量,所以当它离开作用域时(即方法结束),它应该被删除。当其他线程完成其工作时(无论是BW,Thread,BeginInvoke还是Pool),会发生什么情况。 GC是否为每个线程都有单独的参考树? – 2010-06-01 06:37:37