0

我有一个现有的 Silverlight 5 应用程序。我正在向其中添加一个页面,以允许用户处理对第三方数据库系统中数据的大量更新。该应用程序当前使用 WCF RIA 服务通过 SOAP 与第 3 方系统进行通信。更新的功能包含在我创建的 Workflow 4 应用程序中,并作为 SL 应用程序服务器端的程序集引用。最后,该应用程序现在托管在我在 Windows 7 上运行的本地 IIS 7.5 实例中;我也在用 IIS 调试,而不是 VS 开发服务器。

在基础层面,应用程序的功能如下:

  • 选择文本文件
  • 点击“开始”按钮
  • 事件处理程序创建一个用户定义类型的实例,用于跟踪批次
  • 事件处理程序创建一个新BackgroundWorker实例并为DoWorkProgressChangedRunWorkerCompleted事件连接处理程序
  • 事件处理程序调用RunWorkerAsync()

这是事件处理程序的简短代码DoWork,因为这是完成大部分工作的地方。

private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs, BatchContainerControl batchProcess)
{
   var worker = sender as BackgroundWorker;
   // Iterate through each record of data file and call the 'UpdateAddress' function
   // of the AddressDomainService which, in turn, executes the Workflow
   foreach (var item in batchProcess.FileData)
   {
      // Check if operation has been cancelled
      if (worker.CancellationPending)
      {
          doWorkEventArgs.Cancel = true;
          break;
      }

    . . .

      // Invoke THINKComm.CustomerAddressUpdate Workflow via AddressContext
      var invokeOp = _addressDomainContext.UpdateAddress(activityData);
      // 'activityData' is an instance of Dictionary<string, string>

      invokeOp.Completed += (o, args) => InvokeOpOnCompleted(o, args, batchProcess);
   }
}

ProgressChanged和事件的处理程序RunWorkerCompleted,以及所有实例的Completed事件,InvokeOperation在大多数情况下,都会更新 UI 的一部分。如果您认为发布任何代码会有所帮助,我很乐意更新帖子。

说到 UI,事件处理程序更新的部分是两个ProgressBar控件 - 一个在从文件中读取记录时跟踪记录,第二个在第 3 方数据库上发生更新时跟踪记录。

进入实际问题...

我已经毫无问题地处理了 10、100 和 1,000 条记录的文件。然后,我尝试处理包含约 15,000 条记录(或 1,907KB 数据)的完整文件。该过程开始,我可以在调试器输出中看到正在执行工作流。大约进行了四分之一左右,我得到了一个OutOfMemoryException. 这是堆栈跟踪:

at System.ServiceModel.DomainServices.Client.WebDomainClient`1.BeginInvokeCore(InvokeArgs invokeArgs, AsyncCallback callback, Object userState)
at System.ServiceModel.DomainServices.Client.DomainClient.BeginInvoke(InvokeArgs invokeArgs, AsyncCallback callback, Object userState)
at System.ServiceModel.DomainServices.Client.DomainContext.InvokeOperation(String operationName, Type returnType, IDictionary`2 parameters, Boolean hasSideEffects, Action`1 callback, Object userState)
at THINKImportSystem.Web.Address.AddressDomainContext.UpdateAddress(Dictionary`2 activityData)
at THINKImportSystem.BatchProcessPage.BwOnDoWork(Object sender, DoWorkEventArgs doWorkEventArgs, BatchContainerControl batchProcess)
at THINKImportSystem.BatchProcessPage.<>c__DisplayClass10.<StartButtonClick>b__6(Object s, DoWorkEventArgs args)
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.OnRun(Object argument)

然后,JIT 调试器弹出错误Unhandled Error in Silverlight Application Code:4004消息System.ServiceModel.DomainServices.Client.DomainOperationException: Invoke operation 'UpdateAddress' failed. Error HRESULT E_FAIL has been returned from a call to a COM component.

我应该提一下,有时我会先获得 JIT 调试器。我在调试输出中看到线程仍在退出,然后大约 10 或 20 秒后,VS 调试器弹出内存不足异常。

我最好的猜测是,某处的对象(可能与 DomainService 有关?)没有被释放,因此内存使用量正在增加。据我了解,IIS 对应用程序可以使用的内存量进行了限制,但我不知道这里是否是这种情况。

我在想,每次处理文件中的记录时,与其处理相关的对象都会被释放,因此整体内存使用率会很低。但显然我不明白一切是如何执行的!

我还想知道使用 TPL 是否BackgroundWorker会有所作为?

4

0 回答 0