C# SqlDataReader.ReadAsync卡在巨大的blob上
请查看以下代码:C# SqlDataReader.ReadAsync卡在巨大的blob上,c#,async-await,sqldatareader,C#,Async Await,Sqldatareader,请查看以下代码: private async void button1_Click(object sender, EventArgs e) { using (SqlConnection connection = new SqlConnection("some connection string")) { await connection.OpenAsync(); using (SqlCommand command = new SqlCommand
private async void button1_Click(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection("some connection string"))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("select document from myTable where id = 'xyz'", connection))
{
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
if (!await reader.IsDBNullAsync(0))
{
data = reader.GetStream(0);
}
}
}
}
}
文档是我的SQL数据库中的一个图像字段,它可能会变得巨大。虽然它可以很好地处理小Blob(使用200kb Blob测试),但不能处理大Blob(目前使用400mbblob测试)。
当我使用调试器并逐步完成代码时,我看到它与wait reader.ReadAsync()一起进入行中,我们将永远停留在那里
但是,在以下情况下,其效果与预期一致:
- 只需调用reader.Read()(而不是ReadAsync)
- 或者在调用ExecuteReaderAsync时使用:CommandBehavior.SequentialAccess
但是,它并没有结束。调用堆栈中更高级别的调用方是否执行
.Result
或.Wait()
而不是Wait
?如果将.ConfigureAwait(false)
放在代码中的每个await
上,问题是否消失了?代码并不比您看到的多。它只是一个空的windows窗体项目和一个按钮,用于调用示例中的代码。我在一个更大的项目中遇到了这个问题,并创建了这个简单的应用程序来验证它。ConfigureAwait(false)没有任何区别。能否更新显示调用按钮中的代码和当前方法的方法签名的问题?同时显示您如何进行配置等待也会很有用。我更新了它。调用sql读取代码的只是按钮单击事件。不超过这个实际上,在一个更大的vb.net项目中,我在一个web api控制器中遇到了同样的问题。这似乎与blob的大小有关。如果你没有说reader.Read()
,我会怀疑你只是需要等待更长的时间才能完成阅读,但老实说,我现在被难倒了。之所以SequentialAccess
有效,是因为当您处于该模式时Read/ReadAsync()
仅读取标题信息并返回,当不处于该模式时,它必须在返回之前将整行完全读取到内存中。有关更深入的描述,请参阅。调用堆栈中较高级别的调用方是否执行.Result
或.Wait()
而不是Wait
?如果将.ConfigureAwait(false)
放在代码中的每个await
上,问题是否消失了?代码并不比您看到的多。它只是一个空的windows窗体项目和一个按钮,用于调用示例中的代码。我在一个更大的项目中遇到了这个问题,并创建了这个简单的应用程序来验证它。ConfigureAwait(false)没有任何区别。能否更新显示调用按钮中的代码和当前方法的方法签名的问题?同时显示您如何进行配置等待也会很有用。我更新了它。调用sql读取代码的只是按钮单击事件。不超过这个实际上,在一个更大的vb.net项目中,我在一个web api控制器中遇到了同样的问题。这似乎与blob的大小有关。如果你没有说reader.Read()
,我会怀疑你只是需要等待更长的时间才能完成阅读,但老实说,我现在被难倒了。之所以SequentialAccess
有效,是因为当您处于该模式时Read/ReadAsync()
仅读取标题信息并返回,当不处于该模式时,它必须在返回之前将整行完全读取到内存中。有关更深入的描述,请参阅。