Сообщение Re[33]: Можно ли избавиться от async|await? от 19.12.2025 16:46
Изменено 19.12.2025 18:10 Serginio1
Re[33]: Можно ли избавиться от async|await?
Здравствуйте, ·, Вы писали:
S>>·>Какие конкретно камни ты имеешь в виду и как они обходятся в c#?
·>ИЧСХ, ответа не последовало.
Я тебе уже приводил статью, там все расписано.
S>>·>Так ради чего создавать лишнюю сложность в виде копипасты Thread.Sleep/Task.Delay и т.п., чтобы потом пришлось отважно бороться ИИями? В чём ценность сего действа?
S>>·>А просто решать сами бизнес-задачи (хоть с ИИ, хоть без) — не солидно что-ли?
S>>В том, что бы перенести старый код. Только и всего.
·>Т.е. самоцель. Ценность переписывания кода — перенести старый код. Круто, чё. Хобби у тебя, видимо, такое: переписывание кода из пустого в порожнее.
Не самоцель, а необходимость переноса старого кода, для увеличения производительности серверов.
S>>·>Затем, что код с потоками проще, даже если понадобится высокая производительность и много пользователей.
S>>Так и с тасками он не особо то и сложный. Учитывая разного рода Task.WhenAll, Task.WhenAny, CancellationToken
·>Ок, т.е. ты соглашаешься, что код с потоками проще. Надеюсь, ты получил ответ на свой вопрос.
Я соглашаюсь, что он проще, но и примитивнее. Бейсик тоже простой, только вот много на нем не сделаешь.
Многие тоже по началу воротили нос от задач с async/await
С Задачами у тебя намного больше свободы. Кроме того есть прекрасная вещь как TaskCompletionSource c которым ты сам можешь контролировать задачу.
Пример
AsyncProducerConsumerCollection
Используя эту структуру данных, можно написать код, например следующий:
Кроме того и от блокировок можно избавляться
S>>·>Какие конкретно камни ты имеешь в виду и как они обходятся в c#?
·>ИЧСХ, ответа не последовало.
Я тебе уже приводил статью, там все расписано.
S>>·>Так ради чего создавать лишнюю сложность в виде копипасты Thread.Sleep/Task.Delay и т.п., чтобы потом пришлось отважно бороться ИИями? В чём ценность сего действа?
S>>·>А просто решать сами бизнес-задачи (хоть с ИИ, хоть без) — не солидно что-ли?
S>>В том, что бы перенести старый код. Только и всего.
·>Т.е. самоцель. Ценность переписывания кода — перенести старый код. Круто, чё. Хобби у тебя, видимо, такое: переписывание кода из пустого в порожнее.
Не самоцель, а необходимость переноса старого кода, для увеличения производительности серверов.
S>>·>Затем, что код с потоками проще, даже если понадобится высокая производительность и много пользователей.
S>>Так и с тасками он не особо то и сложный. Учитывая разного рода Task.WhenAll, Task.WhenAny, CancellationToken
·>Ок, т.е. ты соглашаешься, что код с потоками проще. Надеюсь, ты получил ответ на свой вопрос.
Я соглашаюсь, что он проще, но и примитивнее. Бейсик тоже простой, только вот много на нем не сделаешь.
Многие тоже по началу воротили нос от задач с async/await
С Задачами у тебя намного больше свободы. Кроме того есть прекрасная вещь как TaskCompletionSource c которым ты сам можешь контролировать задачу.
Пример
AsyncProducerConsumerCollection
public class AsyncProducerConsumerCollection<T>
{
private readonly Queue<T> m_collection = new Queue<T>();
private readonly Queue<TaskCompletionSource<T>> m_waiting =
new Queue<TaskCompletionSource<T>>();
public void Add(T item)
{
TaskCompletionSource<T> tcs = null;
lock (m_collection)
{
if (m_waiting.Count > 0) tcs = m_waiting.Dequeue();
else m_collection.Enqueue(item);
}
if (tcs != null) tcs.TrySetResult(item);
}
public Task<T> Take()
{
lock (m_collection)
{
if (m_collection.Count > 0)
{
return Task.FromResult(m_collection.Dequeue());
}
else
{
var tcs = new TaskCompletionSource<T>();
m_waiting.Enqueue(tcs);
return tcs.Task;
}
}
}
}Используя эту структуру данных, можно написать код, например следующий:
private static AsyncProducerConsumerCollection<int> m_data = …;
…
private static async Task ConsumerAsync()
{
while(true)
{
int nextItem = await m_data.Take();
ProcessNextItem(nextItem);
}
}
…
private static void Produce(int data)
{
m_data.Add(data);
}
Кроме того и от блокировок можно избавляться
// БЫЛО
public class DataProcessor
{
private ThreadLocal<List<int>> cache = new();
private object syncRoot = new();
public void Process()
{
lock(syncRoot)
{
Thread.Sleep(1000);
// обработка
}
}
}
// СТАЛО
public class DataProcessor
{
private AsyncLocal<List<int>> cache = new();
private SemaphoreSlim semaphore = new(1, 1);
public async Task ProcessAsync(CancellationToken ct = default)
{
await semaphore.WaitAsync(ct);
try
{
await Task.Delay(1000, ct);
// асинхронная обработка
}
finally
{
semaphore.Release();
}
}
}Re[33]: Можно ли избавиться от async|await?
Здравствуйте, ·, Вы писали:
S>>·>Какие конкретно камни ты имеешь в виду и как они обходятся в c#?
·>ИЧСХ, ответа не последовало.
Я тебе уже приводил статью, там все расписано.
S>>·>Так ради чего создавать лишнюю сложность в виде копипасты Thread.Sleep/Task.Delay и т.п., чтобы потом пришлось отважно бороться ИИями? В чём ценность сего действа?
S>>·>А просто решать сами бизнес-задачи (хоть с ИИ, хоть без) — не солидно что-ли?
S>>В том, что бы перенести старый код. Только и всего.
·>Т.е. самоцель. Ценность переписывания кода — перенести старый код. Круто, чё. Хобби у тебя, видимо, такое: переписывание кода из пустого в порожнее.
Не самоцель, а необходимость переноса старого кода, для увеличения производительности серверов.
S>>·>Затем, что код с потоками проще, даже если понадобится высокая производительность и много пользователей.
S>>Так и с тасками он не особо то и сложный. Учитывая разного рода Task.WhenAll, Task.WhenAny, CancellationToken
·>Ок, т.е. ты соглашаешься, что код с потоками проще. Надеюсь, ты получил ответ на свой вопрос.
Я соглашаюсь, что он проще, но и примитивнее. Бейсик тоже простой, только вот много на нем не сделаешь.
Многие тоже по началу воротили нос от задач с async/await
С Задачами у тебя намного больше свободы. Кроме того есть прекрасная вещь как TaskCompletionSource c которым ты сам можешь контролировать задачу.
Пример
AsyncProducerConsumerCollection
Используя эту структуру данных, можно написать код, например следующий:
Кроме того и от блокировок можно избавляться
S>>·>Какие конкретно камни ты имеешь в виду и как они обходятся в c#?
·>ИЧСХ, ответа не последовало.
Я тебе уже приводил статью, там все расписано.
S>>·>Так ради чего создавать лишнюю сложность в виде копипасты Thread.Sleep/Task.Delay и т.п., чтобы потом пришлось отважно бороться ИИями? В чём ценность сего действа?
S>>·>А просто решать сами бизнес-задачи (хоть с ИИ, хоть без) — не солидно что-ли?
S>>В том, что бы перенести старый код. Только и всего.
·>Т.е. самоцель. Ценность переписывания кода — перенести старый код. Круто, чё. Хобби у тебя, видимо, такое: переписывание кода из пустого в порожнее.
Не самоцель, а необходимость переноса старого кода, для увеличения производительности серверов.
S>>·>Затем, что код с потоками проще, даже если понадобится высокая производительность и много пользователей.
S>>Так и с тасками он не особо то и сложный. Учитывая разного рода Task.WhenAll, Task.WhenAny, CancellationToken
·>Ок, т.е. ты соглашаешься, что код с потоками проще. Надеюсь, ты получил ответ на свой вопрос.
Я соглашаюсь, что он проще, но и примитивнее. Бейсик тоже простой, только вот много на нем не сделаешь.
Многие тоже по началу воротили нос от задач с async/await
С Задачами у тебя намного больше свободы. Кроме того есть прекрасная вещь как TaskCompletionSource c которым ты сам можешь контролировать задачу.
Пример
AsyncProducerConsumerCollection
public class AsyncProducerConsumerCollection<T>
{
private readonly Queue<T> m_collection = new Queue<T>();
private readonly Queue<TaskCompletionSource<T>> m_waiting =
new Queue<TaskCompletionSource<T>>();
public void Add(T item)
{
TaskCompletionSource<T> tcs = null;
lock (m_collection)
{
if (m_waiting.Count > 0) tcs = m_waiting.Dequeue();
else m_collection.Enqueue(item);
}
if (tcs != null) tcs.TrySetResult(item);
}
public Task<T> Take()
{
lock (m_collection)
{
if (m_collection.Count > 0)
{
return Task.FromResult(m_collection.Dequeue());
}
else
{
var tcs = new TaskCompletionSource<T>();
m_waiting.Enqueue(tcs);
return tcs.Task;
}
}
}
}Используя эту структуру данных, можно написать код, например следующий:
private static AsyncProducerConsumerCollection<int> m_data = …;
…
private static async Task ConsumerAsync()
{
while(true)
{
int nextItem = await m_data.Take();
ProcessNextItem(nextItem);
}
}
…
private static void Produce(int data)
{
m_data.Add(data);
}Кроме того и от блокировок можно избавляться
// БЫЛО
public class DataProcessor
{
private ThreadLocal<List<int>> cache = new();
private object syncRoot = new();
public void Process()
{
lock(syncRoot)
{
Thread.Sleep(1000);
// обработка
}
}
}
// СТАЛО
public class DataProcessor
{
private AsyncLocal<List<int>> cache = new();
private SemaphoreSlim semaphore = new(1, 1);
public async Task ProcessAsync(CancellationToken ct = default)
{
await semaphore.WaitAsync(ct);
try
{
await Task.Delay(1000, ct);
// асинхронная обработка
}
finally
{
semaphore.Release();
}
}
}