Использование TaskCompletionSource для асинхронного ожидания без блокировки?C#

Место общения программистов C#
Ответить
Гость
 Использование TaskCompletionSource для асинхронного ожидания без блокировки?

Сообщение Гость »

У меня есть класс, который обрабатывает бесконечный поток данных. У меня также есть внешние компоненты, которые хотели бы время от времени асинхронно выполнять выборку обработанных данных в специальной форме.
Поскольку может пройти некоторое время, прежде чем будет обработан «следующий элемент». , я бы хотел, чтобы компоненты инспектора данных «ожидали» элемента, чтобы они не блокировались. Это может быть любое количество различных компонентов проверки данных, и если элемент ожидают несколько инспекторов, то хорошо, если все они получат один и тот же экземпляр элемента.
Элементы данных очень большие, поэтому они удаляются сразу после обработки для повышения эффективности использования памяти. И я не хочу делать ничего, что могло бы задержать это (например, публикацию данных в канале или что-то в этом роде)
У меня есть реализация ниже, использующая TaskCompletionSource и блокировки, чтобы убедиться, что tcs работает в разных потоках. Кажется, все работает нормально, но я хотел бы сделать это без блокировки, если это возможно.

Код: Выделить всё

public class DataProcessor
{
private object _sampleDataLock = new object();
private TaskCompletionSource _sampleData;
private Thread _processThread;

public DataProcessor()
{
_processThread = new(ProcessDataLoop);
_processThread.Start();
}

void ProcessDataLoop()
{
while (true)
{
var processedData = ProcessNextData();

//This code in the lock is what I wonder about
lock (_sampleDataLock)
{
_sampleData?.SetResult(processedData.Clone());
_sampleData = null;
}

processedData.Dispose();
}
}

public Task SampleData(TimeSpan timeout)
{
// This is the code I'm wondering how to write without a lock
lock (_sampleDataLock)
{
_sampleData ??= new TaskCompletionSource();
return _sampleData.Task.WithTimeout(timeout);
}
}
}

public class DataInspector
{
private DataProcessor _processor;

public async Task InspectData()
{
//wait up to 30s for an item
var data = await _processor.SampleData(TimeSpan.FromSeconds(30));
// look at data
}
}

Мне интересно, есть ли способ сделать то же самое без блокировки.


Подробнее здесь: https://stackoverflow.com/questions/783 ... ut-locking
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»