Здравствуйте, Mystic Artifact, Вы писали:
MA> Возможно дело в FileStreamAsyncResult, буфер оказывается там. Я бегло не нашел где он пинится. Смущает ещё, что об этой структуре зачем-то осведомлен CLR судя по комментам. Выглядит мутно.
// With our Whidbey async IO & overlapped support for AD unloads,
// we don't strictly need to block here to release resources
// since that support takes care of the pinning & freeing the
// overlapped struct.
// The NativeOverlapped struct keeps a GCHandle to this IAsyncResult object.
// So if the user doesn't call EndRead/EndWrite, a finalizer won't help because
// it'll never get called.
// Overlapped class will take care of the async IO operations in progress
// when an appdomain unload occurs.
Здравствуйте, Jack128, Вы писали:
J>насколько я знаю bytes должен быть зафиксирован до тех пор, пока запись полностью не завершится. А тут буфер разфиксируется сразу после вызова Win32Native.WriteFile. Как это работает??
А это работает?
Возможно дело в FileStreamAsyncResult, буфер оказывается там. Я бегло не нашел где он пинится. Смущает ещё, что об этой структуре зачем-то осведомлен CLR судя по комментам. Выглядит мутно.
Но даже если это работает для регулярных записей, то они WriteFile используют неправильно в иных местах (VerifyHandleIsSync), и это точно.
насколько я знаю bytes должен быть зафиксирован до тех пор, пока запись полностью не завершится. А тут буфер разфиксируется сразу после вызова Win32Native.WriteFile. Как это работает??
Здравствуйте,
MA>> Но даже если это работает для регулярных записей, то они WriteFile используют неправильно в иных местах (VerifyHandleIsSync), и это точно. S>Не совсем так.
С VerifyHandleIsSync я пропустил, что несмотря на то, что передаётся массив, число байт для записи 0 — так что и там проблемы нет.
S>Ужас тот ещё, но в принципе работает.
Да в принципе, ужаса наверное и нет, если точно представлять как всё это работает. Но имхо — могли бы сделать попроще. Впрочем, критиковать всегда легко, особенно незная всей картины.
Здравствуйте, Jack128, Вы писали:
J>Кто нить может пояснить вот это: J>https://referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,2568
J>насколько я знаю bytes должен быть зафиксирован до тех пор, пока запись полностью не завершится. А тут буфер разфиксируется сразу после вызова Win32Native.WriteFile. Как это работает??
Подозреваю, что в ядре делается копия записываемых данных, причём с выравниванием по границе страниц памяти. Копия делается синхронно, а на диск пишется асинхронно. Поэтому можно разфиксировать после возврата управления из Win32Native.WriteFile.
Повторюсь, это всего лишь моё предположение.
ПЭ>Подозреваю, что в ядре делается копия записываемых данных, причём с выравниванием по границе страниц памяти. Копия делается синхронно, а на диск пишется асинхронно. Поэтому можно разфиксировать после возврата управления из Win32Native.WriteFile. ПЭ>Повторюсь, это всего лишь моё предположение.
lpBuffer [in]
A pointer to the buffer containing the data to be written to the file or device.
This buffer must remain valid for the duration of the write operation. The caller must not use this buffer until the write operation is completed.
Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not write to, reallocate, or free the output buffer that a write operation is using until the write operation completes. This can be particularly problematic when using an asynchronous file handle.
Бага. Надо было пришпиленный GCHandle для асинхронной операции создавать. Код, вероятно, работает на честном слове: операции успевают завершиться до того, как сборщик мусора собирает массив либо перемещает его.
Здравствуйте, Jack128, Вы писали:
J>насколько я знаю bytes должен быть зафиксирован до тех пор, пока запись полностью не завершится. А тут буфер разфиксируется сразу после вызова Win32Native.WriteFile. Как это работает??
Можно полюбопытствовать, почему в туда вообще полезли? Что-то не работало?
Здравствуйте, Shmj, Вы писали:
S>Можно полюбопытствовать, почему в туда вообще полезли? Что-то не работало?
Из любопытства и полез.
Я хотел узнать, как происходит натификация о завершении асинхронного IO. Раз они юзают апишку WriteFile, то где то должно быть ожидание на OVERLAPPED.hEvent либо GetOverlappedResult. Но что то я не вижу никаких ожиданий, да и бред это — стопать поток в AsyncIO. Просто изначально я предполагал, что MS будет юзать WriteFileEx + APC, но нет...