public async Task UploadAsync(Stream input) { const int bufferSize = 8040; byte[] buf = new byte[bufferSize]; byte[] chunk = buf; int nr; // Create a buffer around the input so we're guaranteed to read complete chunk sizes: using (var bs = new BufferedStream(input, bufferSize)) { // Perform the first read: nr = await bs.ReadAsync(buf, 0, bufferSize); //if (nr == 0) return; // Did we read less than bufferSize? if (nr < bufferSize) { chunk = new byte[nr]; Array.Copy(buf, chunk, nr); } // Perform the INSERT first: object pk = await db.ExecuteNonQueryAsync(new InsertOperation(cmdInsert, chunk, pkValue)); this.Length += nr; // Early out if we're done: if (nr < bufferSize) { return; } // Use the INSERT query's @pk parameter or fall back to the passed-in value: pk = pk ?? pkValue; // UPDATE while there is more to be uploaded: var update = new UpdateOperation(cmdUpdate, pk); while (nr == bufferSize) { nr = await bs.ReadAsync(buf, 0, bufferSize); // This shouldn't happen: if (nr == 0) { break; } // Crop the chunk array down to the number of bytes actually read: if (nr < bufferSize) { chunk = new byte[nr]; Array.Copy(buf, chunk, nr); } // Perform the UPDATE: update.SetChunk(chunk); await db.ExecuteNonQueryAsync(update); this.Length += nr; } } }