Можно ли вызвать WriteAsync несколько раз одновременно?C#

Место общения программистов C#
Anonymous
Можно ли вызвать WriteAsync несколько раз одновременно?

Сообщение Anonymous »

Я хочу сделать что-то вроде этого
byte[] b1,b2,b3,...
task1=fs.WriteAsync(b1, 0, b1.Length);
task2=fs.WriteAsync(b2, 0, b2.Length);
task3=fs.WriteAsync(b3, 0, b3.Length);
...
Task.WaitAll(task1,task2,task3,...)

Однако я думаю, что проблема существует, если только fs не находится в режиме добавления.
Все зависит от того, обновляет ли WriteAsync позицию файла до или после того, как возвращает свою задачу.
/>Если он обновляет указатель файла перед ожиданием системного вызова, как в псевдокоде старого WriteAsync из https://devblogs.microsoft.com/dotnet/f ... -dotnet-6/
async ValueTask WriteAsyncBefore(ReadOnlyMemory buffer)
{
long oldEndOfFile = GetFileLength(_handle); // 1st sys-call
long newEndOfFile = _position + buffer.Length;

if (newEndOfFile > oldEndOfFile) // this was true for EVERY write to an empty file
{
ExtendTheFile(_handle, newEndOfFile); // 2nd sys-call

SetFilePosition(_handle, newEndOfFile); // 3rd sys-call
_position += buffer.Length;
}

await WriteFile(_handle, buffer); // 4th sys-call
}

проблем не будет, поскольку каждый WriteAsync может использовать правильную позицию +=ed по сравнению с предыдущим.
Однако более вероятна ситуация, когда WriteAsync меняет filepos после WriteFile, вызывая состояние гонки, например новый WriteAsync:
async ValueTask WriteAsyncAfter(ReadOnlyMemory buffer)
{
await WriteFile(_handle, buffer, _position); // the ONLY sys-call
_position += buffer.Length;
}

Настройка filepos вручную не поможет:
pos=0;
fs.Seek(pos,Begin);
task1=fs.WriteAsync(b1, 0, b1.Length);
pos+=b1.Length;
fs.Seek(pos,Begin);
//what if the prev WriteAsync completes and changes file position at this moment?
task2=fs.WriteAsync(b2, 0, b2.Length);
pos+=b2.Length;
fs.Seek(pos,Begin);
//same problem
task3=fs.WriteAsync(b3, 0, b3.Length);


Подробнее здесь: https://stackoverflow.com/questions/788 ... es-at-once

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