Beispiel #1
0
        public void CallbackForCompletedReadAtEndOfEmptyFile()
        {
            FileAsyncIOResult result;

            using (var io = new IOCompletionManager())
                using (var target = new BlockingCompletionTarget(bufferSize: 10))
                    using (
                        SafeFileHandle handle = CreateOrOpenFile(
                            GetFullPath("emptyFile"),
                            FileDesiredAccess.GenericWrite | FileDesiredAccess.GenericRead,
                            FileShare.Read | FileShare.Delete,
                            FileMode.Create))
                    {
                        io.BindFileHandle(handle);

                        unsafe
                        {
                            io.ReadFileOverlapped(target, handle, target.PinBuffer(), target.Buffer.Length, fileOffset: 0);
                        }

                        result = target.Wait();
                    }

            XAssert.IsTrue(result.ErrorIndicatesEndOfFile, "File is empty; EOF read expected");
            XAssert.AreEqual(FileAsyncIOStatus.Failed, result.Status);
        }
Beispiel #2
0
        public void ReadFileToEnd()
        {
            const int NumberOfWords = 1024 * 1024;
            const int TotalSize     = NumberOfWords * 4;

            string path = GetFullPath("file");

            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Delete))
                using (var writer = new BinaryWriter(fs, Encoding.UTF8, leaveOpen: true))
                {
                    for (int i = 0; i < NumberOfWords; i++)
                    {
                        writer.Write((int)i);
                    }
                }

            using (var memoryStream = new MemoryStream(capacity: NumberOfWords * 4))
            {
                using (var io = new IOCompletionManager())
                    using (var target = new BlockingCompletionTarget(bufferSize: 64 * 1024))
                        using (
                            SafeFileHandle handle = CreateOrOpenFile(
                                path,
                                FileDesiredAccess.GenericRead,
                                FileShare.Read | FileShare.Delete,
                                FileMode.Open))
                        {
                            io.BindFileHandle(handle);

                            while (true)
                            {
                                unsafe
                                {
                                    io.ReadFileOverlapped(target, handle, target.PinBuffer(), target.Buffer.Length, fileOffset: memoryStream.Length);
                                }

                                FileAsyncIOResult result = target.Wait();

                                if (result.Status == FileAsyncIOStatus.Failed)
                                {
                                    XAssert.IsTrue(result.ErrorIndicatesEndOfFile, "Unexpected non-EOF read failure.");
                                    break;
                                }
                                else
                                {
                                    XAssert.AreEqual(FileAsyncIOStatus.Succeeded, result.Status);
                                }

                                XAssert.AreNotEqual(0, result.BytesTransferred);
                                XAssert.IsTrue(
                                    memoryStream.Length + result.BytesTransferred <= TotalSize,
                                    "Too many bytes read; Read {0} so far and just got another {1} bytes",
                                    memoryStream.Length,
                                    result.BytesTransferred);
                                memoryStream.Write(target.Buffer, 0, result.BytesTransferred);
                            }
                        }

                memoryStream.Position = 0;

                using (var reader = new BinaryReader(memoryStream, Encoding.UTF8, leaveOpen: true))
                {
                    for (int i = 0; i < NumberOfWords; i++)
                    {
                        XAssert.AreEqual(i, reader.ReadInt32(), "File contents read incorrectly; offset {0}", i * 4);
                    }
                }
            }
        }
Beispiel #3
0
        public void ConcurrentReadsSingleBatch()
        {
            const int NumberOfConcurrentReads = 128; // This should be larger than the batch size at which we allocate OVERLAPPED structures.

            WithPipePair(
                (server, client) =>
            {
                using (var io = new IOCompletionManager())
                {
                    io.BindFileHandle(client);

                    var targets       = new BlockingCompletionTarget[NumberOfConcurrentReads];
                    var completions   = new bool[NumberOfConcurrentReads];
                    var bufferToWrite = new byte[NumberOfConcurrentReads * 4];

                    using (var writeBufferStream = new MemoryStream(bufferToWrite, writable: true))
                    {
                        using (var writer = new BinaryWriter(writeBufferStream))
                        {
                            for (int i = 0; i < NumberOfConcurrentReads; i++)
                            {
                                writer.Write((int)i);
                            }
                        }
                    }

                    try
                    {
                        for (int i = 0; i < targets.Length; i++)
                        {
                            targets[i] = new BlockingCompletionTarget(bufferSize: 8);
                            unsafe
                            {
                                // Note that non-seekable streams mandate an offset of 0 for all requests.
                                // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx
                                io.ReadFileOverlapped(targets[i], client, targets[i].PinBuffer(), 4, fileOffset: 0);
                            }
                        }

                        server.Write(bufferToWrite, 0, bufferToWrite.Length);
                        server.Flush();

                        for (int i = 0; i < targets.Length; i++)
                        {
                            FileAsyncIOResult result = targets[i].Wait();
                            XAssert.AreEqual(FileAsyncIOStatus.Succeeded, result.Status);
                            XAssert.AreEqual(result.BytesTransferred, 4);
                            int completedValue = BitConverter.ToInt32(targets[i].Buffer, 0);

                            XAssert.IsTrue(completedValue >= 0 && completedValue < completions.Length);
                            XAssert.IsFalse(completions[completedValue], "Value {0} completed multiple times", completedValue);
                            completions[completedValue] = true;
                        }
                    }
                    finally
                    {
                        foreach (BlockingCompletionTarget target in targets)
                        {
                            if (target != null)
                            {
                                target.Dispose();
                            }
                        }
                    }
                }
            });
        }