示例#1
0
        public async ReusableTask WriteAsync(ITorrentFileInfo file, long offset, byte[] buffer, int bufferOffset, int count)
        {
            Check.File(file);
            Check.Buffer(buffer);

            if (offset < 0 || offset + count > file.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            using (await Limiter.EnterAsync()) {
                using var rented = await StreamCache.GetOrCreateStreamAsync(file, FileAccess.ReadWrite).ConfigureAwait(false);

                // FileStream.WriteAsync does some work synchronously, according to the profiler.
                // It looks like if the file is too small it is expanded (SetLength is called)
                // synchronously before the asynchronous Write is performed.
                //
                // We also want the Seek operation to execute on the threadpool.
                await MainLoop.SwitchToThreadpool();

                await rented.Stream.SeekAsync(offset).ConfigureAwait(false);

                await rented.Stream.WriteAsync(buffer, bufferOffset, count).ConfigureAwait(false);

                WriteMonitor?.AddDelta(count);
            }
        }
示例#2
0
        public async ReusableTask <int> ReadAsync(ITorrentFileInfo file, long offset, byte[] buffer, int bufferOffset, int count)
        {
            Check.File(file);
            Check.Buffer(buffer);

            if (offset < 0 || offset + count > file.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            using (await Limiter.EnterAsync()) {
                using var rented = await StreamCache.GetOrCreateStreamAsync(file, FileAccess.Read).ConfigureAwait(false);

                await MainLoop.SwitchToThreadpool();

                if (rented.Stream.Length < offset + count)
                {
                    return(0);
                }

                if (rented.Stream.Position != offset)
                {
                    await rented.Stream.SeekAsync(offset);
                }

                ReadMonitor?.AddDelta(count);
                return(await rented.Stream.ReadAsync(buffer, bufferOffset, count));
            }
        }