I want to do something like this
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,...)
<code>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,...)
</code>
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,...)
However, I think there is a problem, unless fs is in append mode.
It all depends on whether WriteAsync updates file position before or after it returns its task.
If it updates file pointer before awaiting the syscall, like the pseudocode of old WriteAsync from https://devblogs.microsoft.com/dotnet/file-io-improvements-in-dotnet-6/
<code>async ValueTask WriteAsyncBefore(ReadOnlyMemory<byte> 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
<code>async ValueTask WriteAsyncBefore(ReadOnlyMemory<byte> 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
}
</code>
async ValueTask WriteAsyncBefore(ReadOnlyMemory<byte> 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
}
there will be no issue, since each WriteAsync is able to use the correct +=ed position from the previous one.
However, the more likely situation is that WriteAsync changes filepos after WriteFile, causing race condition, such as the new WriteAsync:
<code>async ValueTask WriteAsyncAfter(ReadOnlyMemory<byte> buffer)
await WriteFile(_handle, buffer, _position); // the ONLY sys-call
_position += buffer.Length;
<code>async ValueTask WriteAsyncAfter(ReadOnlyMemory<byte> buffer)
{
await WriteFile(_handle, buffer, _position); // the ONLY sys-call
_position += buffer.Length;
}
</code>
async ValueTask WriteAsyncAfter(ReadOnlyMemory<byte> buffer)
{
await WriteFile(_handle, buffer, _position); // the ONLY sys-call
_position += buffer.Length;
}
Manually setting filepos is of no help:
task1=fs.WriteAsync(b1, 0, b1.Length);
//what if the prev WriteAsync completes and changes file position at this moment?
task2=fs.WriteAsync(b2, 0, b2.Length);
task3=fs.WriteAsync(b3, 0, b3.Length);
<code>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);
</code>
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);