2011-12-20 10 views
4

私は、コールバックを使用して(最後に単一のContinueWith()コールバックではなく)段階的にデータをフィードするタスクを長時間実行しています。タスクのインスタンスをタスクのデリゲートに渡す

私は(Task.CurrentIdを使用して)タスクの識別目的のために戻って、このコールバックでオブジェクトのタスクを渡すことができるようにしたい

しかし、私は、タスクデリゲートにTaskオブジェクトを渡す方法を動作することはできません。これを行うためのオーバーロードがないように見えます。その時点でタスクオブジェクトが定義されていないため、クロージャを使用することはできません。

例えば、

public Task StartDoingSomeStuff(CallbackDelegate callback) 
{ 
    Task task = Task.Factory.StartNew(() => 
    { 
     while(whatever) 
     { 
      var results = DoSomeStuff(); 
      callback(results, task); //CS0165. How do I get hold of the task? 
     } 
    }); 

    return task; 
} 

ができます:

エラーCS0165:未割り当てのローカル変数 'タスク' 変数を宣言し、二つの文にそれにタスクを割り当てる

答えて

5

スプリットの使用。タスクが割り当てられている前に、変数を使用していないことを確認してください:

public Task StartDoingSomeStuff(CallbackDelegate callback) 
{ 
    Task task = null; 

    task = Task.Factory.StartNew(() => 
    { 
     while(whatever) 
     { 
      var results = DoSomeStuff(); 
      callback(results, task); //CS0165. How do I get hold of the task? 
     } 
    }); 

    return task; 
} 
+0

+1私は同じことを書いていました。 :) 'DoSomeStuff()'の後の行に 'signal.Wait();'を移動させ、ロックを遅らせることもできます。 – Groo

+0

'ManualResetEventSlim signal'の代わりに' lock'文を使う方がいいかもしれません。 @Grooがコメントした後、私はそれに応じて答えを変更しました。 – dtb

+0

が合意しました。私はまだ 'callback'行だけをロックしていますが、パフォーマンスの差は最小限です。 – Groo

0

タスクにマッピングする辞書のキーは、タスクのアクションに状態としてキーを渡します

var taskMap = new Dictionary<object, Task>(); 
var taskKey = new object(); 
taskMap.Add(taskKey, Task.Factory.StartNew(key => { callback(results, key); }, taskKey)); 

もちろん、あなたがまたはあなたのシナリオに合わない場合があり、キー、からタスクを検索する必要があります。

+2

[dtb did](http://stackoverflow.com/a/8575136/69809)のように同期すると、問題ありません。これにより競合状態を危険にさらし、バックグラウンドスレッドは 'task'が割り当てられる前にその作業を行います。 – Groo

1

別の解決策は、タスクキーと作成することです:それは悪い習慣ですが、これは動作するはず

public Task StartDoingSomeStuff(CallbackDelegate callback) 
{ 
    var gate = new object(); 
    lock (gate) 
    { 
     Task task = null; 
     task = Task.Factory.StartNew(() => 
     { 
      lock (gate) 
      { 
       while (whatever) 
       { 
        var results = DoSomeStuff(); 
        callback(results, task); 
       } 
      } 
     }); 
     return task; 
    } 
} 
関連する問題