5

私は C# と Threading の初心者で、これは非常に単純な質問ですが、本当に行き詰まっています。このサイトで検索しましたが、私のシナリオに似た答えが見つかりませんでした:

Parent() というメソッドがあり、その中で型付きリストを作成し、n 回ごとにそれを Task に渡します。リストが増え続けるため、いつリストをクリアしてメモリを解放するかという問題があります。タスクの最後にリストをクリアしようとしましたが、Parent メソッドでリストをクリアすると、スレッドでリストが空になります。

誰かが私を助けることができますか?これは非常に単純な問題であることは承知していますが、助けていただければ幸いです。

    public void Parent()
    {
     List<MyType> list = new List<MyType>();
     for (int i = 0; i< N; i++)
     {
        list.Add(new MyType {Var = "blah"});

      if ( i% 10 == 0) //every tentth time we send a task out tou a thread
      {
       Task.Factory.StartNew(() => WriteToDB(new List<MyType>(list))); 
       //here I am              sending a new instance of the list

        //Task.Factory.StartNew(() => WriteToDB((list))); 
        //here I am sending same instance

        list.Clear();

         //if I clear here the list sent to the WriteToDB is empty
        //if I do not, the memory keeps growing up and crashes the app 
      }

      private void WriteToDB(List<MyType> list)
      {
       //do some calculations with the list 
       //insert into db 
       list.Clear(); 
      }
     }
   }
4

3 に答える 3

7

閉鎖バグがあります。

ラムダ() => WriteToDB(new List<MyType>(list))は、新しいTask開始まで実行されません。これは、 への呼び出しの後である場合がありますlist.Clear()

修正は、ラムダの外側のリストのコピーをキャプチャすることです。

var chunk = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(chunk));

list.Clear();
于 2012-12-01T10:39:17.773 に答える
1
if ( i% 10 == 0) //every tentth time we send a task out tou a thread
{
   // clone your list before starting the task
   var listToProcess = new List<MyType>(list);
   list.Clear();

   Task.Factory.StartNew(() => WriteToDB(listToProcess)); 
}
于 2012-12-01T10:56:32.053 に答える
1

スレッドを開始する前に新しいリストを作成するだけです:

var newList = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(newList)); 
list.Clear();

このようにして、新しいスレッドが開始する前に新しいリストの準備が整うので、元のリストをすぐにクリアしても安全です。

于 2012-12-01T10:34:56.117 に答える