Как я могу предотвратить синхронное продолжение задания?

У меня есть некоторый код библиотеки (сокет сети), который обеспечиваетTaskAPI для ожидающих ответов на запросы, основанный на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();
    }
}

Ответы на вопрос(6)

Ваш ответ на вопрос