gpt4 book ai didi

c# - FileStream.ReadAsync 有时会同步完成吗?

转载 作者:太空狗 更新时间:2023-10-29 23:14:59 26 4
gpt4 key购买 nike

试一试。使用单个按钮和按钮单击事件的以下代码设置新的 Windows 窗体应用程序:

private async void button1_Click(object sender, EventArgs e)
{
using (var file = File.OpenRead(@"C:\Temp\Sample.txt"))
{
byte[] buffer = new byte[4096];
int threadId = Thread.CurrentThread.ManagedThreadId;
int read = await file.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
Debug.Assert(threadId != Thread.CurrentThread.ManagedThreadId);
}
}

然后运行应用程序并快速单击按钮。如果您的经历与我的一样,您会发现有时它会按预期工作,但有时 Debug.Assert 会失败。

基于我对ConfigureAwait的理解as explained on Stephen Cleary’s blog ,为 continueOnCapturedContext 传递 false 应该指示任务不同步回“主”上下文(在本例中为 UI 线程),并且应该在线程池上继续执行。

为什么断言会随机失败?我只能假设 ReadAsync 有时不会在后台线程上完成,即它会同步完成。

此行为符合知识库文章 156932 - Asynchronous Disk I/O Appears as Synchronous on Windows :

Most I/O drivers (disk, communications, and others) have special case code where, if an I/O request can be completed "immediately," the operation will be completed and the ReadFile or WriteFile function will return TRUE. In all ways, these types of operations appear to be synchronous. For a disk device, typically, an I/O request can be completed "immediately" when the data is cached in memory.

我的假设和测试应用是否正确? ReadAsync 方法有时可以同步完成吗?有没有办法保证执行将始终在后台线程上继续?

这个问题对我的应用程序造成了严重破坏,该应用程序使用 COM 对象,要求我始终知道哪个线程正在执行。

Windows 7 64 位、.NET 4.5.1

最佳答案

Can the ReadAsync method sometimes complete synchronously?

是的。由于操作系统级别和 .NET 流类型中的缓冲区,这种情况并不少见。

Is there a way to guarantee that execution will always continue on a background thread?

如果您总是希望代码在线程池线程上执行,则使用Task.Run:

private async void button1_Click(object sender, EventArgs e)
{
using (var file = File.OpenRead(@"C:\Temp\Sample.txt"))
{
byte[] buffer = new byte[4096];
int threadId = Thread.CurrentThread.ManagedThreadId;
int read = await file.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
await Task.Run(() =>
{
Debug.Assert(threadId != Thread.CurrentThread.ManagedThreadId);
}).ConfigureAwait(false);
}
}

ConfigureAwait 是一个优化提示,而不是移动到后台线程的命令。如果操作已经完成,ConfigureAwait 无效。在这种情况下,await 跟在 "fast path" 之后。这实质上意味着它会同步继续,因此任何 ConfigureAwait 提示都将被忽略。

关于c# - FileStream.ReadAsync 有时会同步完成吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22494420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com