You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#284 added true async record reading but deliberately deferred three pieces (listed in that PR):
Async table open — DbfTable's constructors read the header and column descriptors synchronously, so ExecuteReaderAsync still does a small synchronous read at open. Requires a static factory (DbfTable.OpenAsync(...)) since constructors cannot await; DbfDbCommand could then offer a genuinely async ExecuteDbDataReaderAsync.
Async memo resolution — memo values are resolved during span parsing via a synchronous BinaryReader (DbfMemo), so a table with memo columns performs sync I/O inside ReadAsync. Needs the memo subsystem moved off BinaryReader onto buffered reads with async variants, and a way for value parsing to defer memo fetches (e.g. parse block pointers, resolve lazily/asynchronously on access).
IAsyncEnumerable<DbfRecord> on DbfTable — parked on a real design question: yielding the mutated reused record is a footgun (ToListAsync would produce N references to one object), yielding fresh records allocates the full value-object set per row. The typed builder (Add typed queries: DbfQuery<T> builder and Dapper-style Query<T> (SQL support phase 5) #290) sidesteps this with materialised Ts; a raw-record async stream should probably yield fresh records and document the cost, or take the reused record as a parameter like Read(DbfRecord) does.
These fit naturally as one PR or three small ones.
Context
#284 added true async record reading but deliberately deferred three pieces (listed in that PR):
DbfTable's constructors read the header and column descriptors synchronously, soExecuteReaderAsyncstill does a small synchronous read at open. Requires a static factory (DbfTable.OpenAsync(...)) since constructors cannot await;DbfDbCommandcould then offer a genuinely asyncExecuteDbDataReaderAsync.BinaryReader(DbfMemo), so a table with memo columns performs sync I/O insideReadAsync. Needs the memo subsystem moved offBinaryReaderonto buffered reads with async variants, and a way for value parsing to defer memo fetches (e.g. parse block pointers, resolve lazily/asynchronously on access).IAsyncEnumerable<DbfRecord>onDbfTable— parked on a real design question: yielding the mutated reused record is a footgun (ToListAsyncwould produce N references to one object), yielding fresh records allocates the full value-object set per row. The typed builder (Add typed queries: DbfQuery<T> builder and Dapper-style Query<T> (SQL support phase 5) #290) sidesteps this with materialisedTs; a raw-record async stream should probably yield fresh records and document the cost, or take the reused record as a parameter likeRead(DbfRecord)does.These fit naturally as one PR or three small ones.
🤖 Generated with Claude Code