如何在 .Net 6 中使用 CsvHelper 异步编写数据?

huangapple go评论70阅读模式
英文:

How to write asynchronously using CsvHelper in .Net 6

问题

CsvHelper 30.0.0 in .Net 6.0 中是否可以使用异步方式编写?

WriteRecord(s) 方法一直引发此错误:
> Microsoft.AspNetCore.Server.Kestrel.Core:不允许同步操作。请调用 WriteAsync 或将 AllowSynchronousIO 设置为 true。

这是我尝试的第一种方法(来自 https://stackoverflow.com/a/55928375/18463829):

foreach (var item in items )
  {
    csvWriter.WriteRecord(item);
    await csvWriter.NextRecordAsync();
  }

我也尝试了这个:

await csvWriter.WriteRecordsAsync(items);

但结果相同。

在上面的代码中,“items” 是一个简单 DTO 的 List。我们有许多 DTO,但它们都是简单的对象,它们都会生成相同的错误。这是一个示例 DTO(其中一些名称已更改):

using System;

namespace CompanyName.Domain.DTO
{
    public class SomeDTO
    {
        public DateTimeOffset StartDateEST { get; set; }
        public int Value { get; set; }
        public long SomeID { get; set; }
        public short SomeLevel { get; set; }
    }
}

附加背景信息:

这是一个 .Net 6.0 Azure Functions 应用程序,目标是 Azure Functions v4,使用 CsvHelper 30.0.0。它是一组具有多个操作的 API。这是一个旧应用程序,在我们升级到 .Net 6.0 时引入了此问题。当消费者以 JSON 格式请求数据时,所有端点都按预期工作,但当他们以 CSV 请求时,出现了上述问题。

部署到 Azure 时,不会引发错误。日志中没有任何内容。端点返回 200 “ok” 响应,但没有数据(尽管有很多数据,如果消费者以 JSON 请求,则返回数据相同)。

当我在本地运行时,我可以在控制台中看到上面的错误消息。我还可以在 VS 输出窗口中看到以下内容:

Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll

但是,我似乎无法让 Visual Studio 捕获堆栈跟踪。我一直在寻找我可能遗漏的某种设置,但没有找到。就好像 Visual Studio 不知道错误正在发生一样。

英文:

Is it possible to write asynchronously using CsvHelper 30.0.0 in .Net 6.0?

The WriteRecord(s) method consistently throws this error:
> Microsoft.AspNetCore.Server.Kestrel.Core: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.

Here is the first approach I tried (which I got from https://stackoverflow.com/a/55928375/18463829):

foreach (var item in items )
  {
    csvWriter.WriteRecord(item);
    await csvWriter.NextRecordAsync();
  }

I also tried this:

await csvWriter.WriteRecordsAsync(items);

But that has the same result.

In the code above, "items" is a List of simple DTO's. We have many DTO's but all of them are simple objects, and they all generate the same error. Here is a sample DTO (with a couple of names changed):

using System;

namespace CompanyName.Domain.DTO
{
    public class SomeDTO
    {
        public DateTimeOffset StartDateEST { get; set; }
        public int Value { get; set; }
        public long SomeID { get; set; }
        public short SomeLevel { get; set; }
    }
}

Additional background info:

This is a .Net 6.0 Azure Functions app, targeting Azure Functions v4, and using CsvHelper 30.0.0. It is a set of APIs, each with multiple operations. It is an old app, and this issue was introduced when we upgraded to .Net 6.0. All of the endpoints work as expected when the consumer requests the data in JSON format, but when they request CSV, we have the issue described above.

When deployed to Azure, there is no error thrown. There is nothing in the logs. The endpoints return a 200 "ok" response, but with no data (even though there is lots of data, and the same request returns the data if the consumer requests it in JSON).

When I run it locally, I can see the above error message in the console. I can also see this in the VS Output window:

Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll

However, I cannot seem to get Visual Studio to capture the stack trace. I've been searching for some kind of setting that I'm missing, but no luck. It's as if Visual Studio is unaware that the error is happening.

答案1

得分: 1

在查看@dbc提供的代码示例后,我意识到现有的代码缺少了一些 "await" 关键字。例如,它原本是这样的:

using (csvWriter)

而应该是这样的:

await using (csvWriter)

我添加了这些关键字,现在它可以正常工作。

顺便说一下,在我发布这个问题之前,我搜索了CsvHelper的文档,但没有找到任何信息。相反,我找到了 "即将推出..."。根据问题中引用的StackOverflow 答案,我认为没有名为csvWriter.WriteRecordsAsync()的方法。由于那个答案对我不起作用,并且已经有几年了,我认为它已经过时,因此发布了这个问题。

英文:

After looking at the code samples provided by @dbc, I realized the existing code was missing a couple of "await" keywords. For example, it had:

using (csvWriter)

Where it should have had:

await using (csvWriter)

I added them in, and now it works fine.

FWIW, before I posted this question, I searched for CsvHelper documentation, but did not find any. Instead, what I found was "Coming soon..." Based on the StackOverflow answer referenced in the question, I thought there was no such method as csvWriter.WriteRecordsAsync(). Since that answer did not work for me, and it is a few years old, I figured it was out-of-date, and hence posted this one.

huangapple
  • 本文由 发表于 2023年6月1日 21:53:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76382645.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定