Task
.NET을 기반으로 요청에 대한 보류중인 응답에 대한 기반 API를 제공하는 라이브러리 (소켓 네트워킹) 코드가 TaskCompletionSource<T>
있습니다. 그러나 동기식 연속을 방지하는 것이 불가능 해 보인다는 점에서 TPL에는 성가심이 있습니다. 내가 것 처럼 할 수 있도록하는 중입니다 :
TaskCompletionSource<T>
발신자가을 (를) 첨부하는 것을 허용해서는 안된다고 알리TaskContinuationOptions.ExecuteSynchronously
거나- 대신 풀을 사용하여 무시해야 함 을 지정하는 방식으로 결과 (
SetResult
/TrySetResult
)를 설정합니다.TaskContinuationOptions.ExecuteSynchronously
특히, 내가 가진 문제는 들어오는 데이터가 전용 리더에 의해 처리되고 있으며 호출자가 첨부 TaskContinuationOptions.ExecuteSynchronously
할 수있는 경우 리더를 지연시킬 수 있다는 것입니다 (단지 그 이상에 영향을 미침). 이전에, 내가 여부를 감지 몇 가지 해커에 의해이 문제를 해결 일한 어떤 연속성을가 존재하고, 그들이하는 경우는 위에 완료를 밀어 ThreadPool
완료 처리되지되므로 발신자가 자신의 작업 대기열을 포화 경우, 그러나이 상당한 영향을 적시에. 그들이 Task.Wait()
(또는 유사한) 사용하고 있다면 본질적으로 교착 상태가 될 것입니다. 마찬가지로 독자가 워커를 사용하는 대신 전용 스레드에있는 이유입니다.
그래서; TPL 팀에 잔소리를하기 전에 옵션이 없나요?
키 포인트:
- 외부 발신자가 내 대화 목록을 탈취하는 것을 원하지 않습니다.
ThreadPool
풀이 포화 상태 일 때 작동해야하므로 구현으로 사용할 수 없습니다.
아래 예는 출력을 생성합니다 (순서는 타이밍에 따라 다를 수 있음).
Continuation on: Main thread
Press [return]
Continuation on: Thread pool
문제는 임의의 호출자가 "메인 스레드"에서 계속 될 수 있다는 사실입니다. 실제 코드에서 이것은 기본 판독기를 방해합니다. 나쁜 것들!
암호:
using System;
using System.Threading;
using System.Threading.Tasks;
static class Program
{
static void Identify()
{
var thread = Thread.CurrentThread;
string name = thread.IsThreadPoolThread
? "Thread pool" : thread.Name;
if (string.IsNullOrEmpty(name))
name = "#" + thread.ManagedThreadId;
Console.WriteLine("Continuation on: " + name);
}
static void Main()
{
Thread.CurrentThread.Name = "Main thread";
var source = new TaskCompletionSource<int>();
var task = source.Task;
task.ContinueWith(delegate {
Identify();
});
task.ContinueWith(delegate {
Identify();
}, TaskContinuationOptions.ExecuteSynchronously);
source.TrySetResult(123);
Console.WriteLine("Press [return]");
Console.ReadLine();
}
}
TaskCompletionSource
에 직접 전화를 방지하기 위해 내 자신의 API와ContinueWith
도 있기 때문에TaskCompletionSource
,도Task
그들로부터 상속하지 옷 잘 않습니다.