3

私はいくつかの非同期メソッドを持っています:

// not ideal
private TaskCompletionSource<A> _tcsA;
private TaskCompletionSource<A> _tcsB;
private TaskCompletionSource<A> _tcsC;
...

public Task<A> GetAAsync() {
  _currentTask = TaskType.A;
  _tcsA = new TaskCompletionSource<A>();
  // some complex non-sync task, using http/events that ends with Complete();
  // QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
  return _tcsA.Task;
}

public Task<B> GetBAsync() {
  _currentTask = TaskType.B;
  _tcsB = new TaskCompletionSource<B>();
  // some complex non-sync task, using http/events that ends with Complete();
  // QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
  return _tcsB.Task;
}

public Task<C> GetCAsync() {
  _currentTask = TaskType.C;
  _tcsC = new TaskCompletionSource<C>();
  // some complex non-sync task, using http/events that ends with Complete();
  // QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
  return _tcsC.Task;
}

// called by an external source, a http listener / processor
// this should complete the async call by the client and return results
public void Complete(Result result) {
  switch (_currentTask) {
    case TaskType.A:
      _tcsA.SetResult(new A());
      break;
    case TaskType.B:
      _tcsB.SetResult(new B());
      break;
    case TaskType.C:
      _tcsC.SetResult(new C());
      break;
  }

  _currentTask = TaskType.None;
}

上記は、簡単にするための半疑似コードです。私は次のようにメソッドの1つを呼び出します:

A a = await service.GetAAsync();

ここでの問題はTaskCompletionSource<T>一般的なことです。このように 100 個のメソッドがある場合、戻り値の型ごとに変数を作成する必要があります。ただし、一度に呼び出すことができるメソッドは1 つだけTaskCompletionSourceなので、 にタイプせずに単一のを使用すると便利ですobject (TaskCompletionSource<object>)

私はしたくない:

object a = await service.GetAAsync();

クライアントによるキャストが必要になるためです。したがって、最善の解決策は、単一の を使用することですが、TaskCompletionSource何らかの方法で入力することです。または、代わりに の Dictionary を持つこともできTaskCompletionSourceます。どちらも私には不可能に思えます。

これをどのように解決すればよいですか?

アップデート:

私の状況の背景については、次をご覧ください。 切断されたシナリオで同期コードを非同期待機にラップする

4

2 に答える 2