0

既存の Silverlight 5 アプリケーションがあります。ユーザーがサードパーティのデータベース システム内のデータに対する一括更新を処理できるように、ページを追加しています。アプリケーションは現在、WCF RIA サービスを使用して、SOAP 経由でサード パーティ システムと通信します。更新の機能は、私が作成したワークフロー 4 アプリケーションに含まれており、SL アプリケーションのサーバー側でアセンブリとして参照されます。最後に、アプリケーションは現在、Windows 7 で実行されている IIS 7.5 のローカル インスタンスでホストされています。VS開発サーバーではなく、IISでもデバッグしています。

基本レベルでは、アプリケーションは次のように機能します。

  • テキストファイルを選択
  • 「開始」ボタンをクリック
  • イベント ハンドラーは、バッチを追跡するユーザー定義の Type のインスタンスを作成します。
  • イベント ハンドラは新しいBackgroundWorkerインスタンスを作成し、DoWorkProgressChanged、およびRunWorkerCompletedイベントのハンドラを結び付けます
  • イベント ハンドラの呼び出し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);
   }
}

ProgressChangedRunWorkerCompletedイベントのハンドラー、およびインスタンス all のCompletedイベントはInvokeOperation、ほとんどの場合、UI の一部を更新します。そのコードの投稿が役立つと思われる場合は、喜んで投稿を更新します。

UI といえば、イベント ハンドラーによって更新される部分は 2 つのProgressBarコントロールです。1 つはファイルから読み取られたときにレコードを追跡し、もう 1 つはサード パーティ データベースで更新が行われたときにレコードを追跡します。

実際の問題にたどり着く...

10、100、および 1,000 レコードのファイルを問題なく処理しました。次に、約 15,000 レコード (または 1,907KB のデータ) を含む完全なファイルを処理しようとしました。プロセスが開始され、ワー​​クフローが実行されていることがデバッガーの出力で確認できます。約4分の1かそこらで、私は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