我有以下同步代码,运行良好:
private void GenerateExportOutput()
{
using StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
if (this.WikiPagesToExport.IsEmpty)
{
return;
}
var wanted = new SortedDictionary<string, WikiPage>(this.WikiPagesToExport, StringComparer.Ordinal);
foreach (var title in wanted.Keys)
{
writer.WriteLine(title);
}
}
Run Code Online (Sandbox Code Playgroud)
我想将其更改为异步。所以:
private async Task GenerateExportOutputAsync()
{
using StreamWriter writer = new(Coordinator.OutputDirectory + @"\export.txt");
if (this.WikiPagesToExport.IsEmpty)
{
return;
}
var wanted = new SortedDictionary<string, WikiPage>(this.WikiPagesToExport, StringComparer.Ordinal);
foreach (var title in wanted.Keys)
{
await writer.WriteLineAsync(title).ConfigureAwait(false);
}
await writer.FlushAsync().ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
哪个编译。但我使用的分析器之一(Meziantou.Analyzer)现在建议我“更喜欢使用‘await using’”。我从来没有使用过await using(尽管我过去尝试过几次并且总是遇到现在遇到的相同问题)。但我想使用它,所以:
await using StreamWriter writer = …Run Code Online (Sandbox Code Playgroud) 我一直在熟悉C#8和.NET Core 3.0中(计划要添加的)某些内容,并且不确定实现IAsyncDisposable的正确方法(在撰写本文时,此链接实际上没有任何指导) )。
特别是,我不清楚在未明确处理实例的情况下该怎么办-也就是说,该实例未包装在中async using(...),.DisposeAsync()也未明确调用。
我首先想到的是做与实现IDisposable时相同的事情:
DisposeAsync()实现调用DisposeAsync(bool disposing)带有disposing: true~MyType()),该终结器调用DisposeAsync(disposing: false)DisposeAsync(bool disposing)实际上释放和/或处置所有内容,并抑制if的终结disposing == true。我担心的是,没有什么可以等待DisposeAsync(bool)finalizer 的结果,而显式地等待finalizer似乎真的很危险。
当然,“只是泄漏”似乎也不理想。
为了具体起见,这里有一个(简化的)示例类,它确实有一个终结器:
internal sealed class TestAsyncReader: IAsyncDisposable
{
private bool IsDisposed => Inner == null;
private TextReader Inner;
internal TestAsyncReader(TextReader inner)
{
Inner = inner;
}
// the question is, should this exist?
~TestAsyncReader()
{
DisposeAsync(disposing: false);
}
private …Run Code Online (Sandbox Code Playgroud) 我可以使用using var:
await foreach (var response in _container.GetItemQueryStreamIterator(query))
{
using var safeResponse = response;
//use the safeResponse
}
Run Code Online (Sandbox Code Playgroud)
或者我应该这样做:
await foreach (var response in _container.GetItemQueryStreamIterator(query))
{
try {
//use response
} finally {
response?.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
或者我可以不去处理因为迭代器是一个IAsyncDisposable并且await foreach会为我做吗?
await foreach (var response in _container.GetItemQueryStreamIterator(query))
{
//use the response
}
Run Code Online (Sandbox Code Playgroud) 我有一个非常奇怪的编译时错误,我在谷歌中检查的任何地方我都看到我的语法应该绝对没问题。
我的项目是 .net-5 并用 C# 语言编写。
public async Task Init()
{
using IEngineProviderAsync provider = await CreateProviderAsync();
}
Run Code Online (Sandbox Code Playgroud)
CS8418“IEngineProviderAsync”:using 语句中使用的类型必须可隐式转换为“system.idisposable”。您的意思是“等待使用”而不是“使用”吗?
我搜索了 CS8418 但没有数据。微软链接不起作用https://docs.microsoft.com/en-us/dotnet/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error?f1url=% 3FappId%3Droslyn%26k%3Dk(CS8418)
考虑以下来自Microsoft 文档的代码:
using FileStream createStream = File.Create(fileName);
// ...write to stream etc..
await createStream.DisposeAsync(); // <- isn't this done automatically because of the using clause in the first line`?
Run Code Online (Sandbox Code Playgroud)
调用该方法不是DisposeAsync()多余的吗?
我有下一个方法:
public async Task<IEnumerable<Quote>> GetQuotesAsync()
{
using var connection = new SqlConnection(_connectionString);
var allQuotes = await connection.QueryAsync<Quote>(@"SELECT [Symbol], [Bid], [Ask], [Digits] FROM [QuoteEngine].[RealtimeData]");
return allQuotes;
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,也很清楚,连接将放在示波器的末尾。
但是resharper建议将其更改为:
public async Task<IEnumerable<Quote>> GetQuotesAsync()
{
await using var connection = new SqlConnection(_connectionString);
var allQuotes = await connection.QueryAsync<Quote>(@"SELECT [Symbol], [Bid], [Ask], [Digits] FROM [QuoteEngine].[RealtimeData]");
return allQuotes;
}
Run Code Online (Sandbox Code Playgroud)
它在使用前增加了等待,并且代码已成功编译。这是什么意思,什么时候需要做?
我正要使用下面的 C# 代码。
await using (var producerClient = new EventHubProducerClient(ConnectionString, EventHubName))
{
using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();
eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(eventData)));
await producerClient.SendAsync(eventBatch);
}
Run Code Online (Sandbox Code Playgroud)
但是在构建服务器中这会失败,因为上面是 C# 8.0 代码并且构建服务器只支持 C# 7.0 代码。有人可以帮我将上面的代码从 C# 8.0 转换为 C# 7.0,因为我无法让它工作吗?
c# ×7
using ×4
async-await ×3
asynchronous ×3
.net ×2
.net-5 ×1
asp.net-core ×1
c#-7.0 ×1
c#-8.0 ×1
dispose ×1
filestream ×1
resharper ×1