我不知道如何在 c# Task 中正确填充 List<string>
I can't figure out how to populate a List<string> inside a c# Task correctly
我写了这段荒谬的代码只是为了弄清楚:
- 如果我使用
CallingFunctionAsync_v1
与 CallingFunctionAsync_v2
有区别吗?
如果是这样,有人可以解释为什么吗?
定义:
class WorkHorse
{
const int RECORD_SIZE = 12;
public async Task<List<string>> DoTheThingAsync_v1(CancellationToken cancellationToken)
{
List<string> theList = new List<string>();
byte[] buffer = new byte[RECORD_SIZE];
using var fs = File.OpenRead("awesome_stuff.bin");
int read;
while ((read = await fs.ReadAsync(buffer, 0, RECORD_SIZE, cancellationToken).ConfigureAwait(false)) != 0)
{
theList.Add(Encoding.UTF8.GetString(buffer, 0, RECORD_SIZE));
}
return theList;
}
public async Task DoTheThingAsync_v2(List<string> theList, CancellationToken cancellationToken)
{
byte[] buffer = new byte[RECORD_SIZE];
using var fs = File.OpenRead("awesome_stuff.bin");
int read;
while ((read = await fs.ReadAsync(buffer, 0, RECORD_SIZE, cancellationToken).ConfigureAwait(false)) != 0)
{
theList.Add(Encoding.UTF8.GetString(buffer, 0, RECORD_SIZE));
}
}
}
用法:
class FunTimes
{
List<string> TheStrings;
public async Task CallingFunctionAsync_v1(CancellationToken cancellationToken)
{
this.TheStrings = await new WorkHorse().DoTheThingAsync_v1(cancellationToken).ConfigureAwait(false);
}
public Task CallingFunctionAsync_v2(CancellationToken cancellationToken)
{
this.TheStrings = new List<string>();
return new WorkHorse().DoTheThingAsync_v2(this.TheStrings, cancellationToken);
}
}
V1 是更好的方法。它是一个纯粹的黑盒函数,总是 returns 一个新列表。
V2 需要 List<string>
的初始化实例,这很容易出错。您可以轻松传递 null 并遇到问题。然后,由于这些是异步方法,您可以同时 运行 V2,并且您将在已传递的列表上出现竞争条件。
我写了这段荒谬的代码只是为了弄清楚:
- 如果我使用
CallingFunctionAsync_v1
与CallingFunctionAsync_v2
有区别吗?
如果是这样,有人可以解释为什么吗?
定义:
class WorkHorse
{
const int RECORD_SIZE = 12;
public async Task<List<string>> DoTheThingAsync_v1(CancellationToken cancellationToken)
{
List<string> theList = new List<string>();
byte[] buffer = new byte[RECORD_SIZE];
using var fs = File.OpenRead("awesome_stuff.bin");
int read;
while ((read = await fs.ReadAsync(buffer, 0, RECORD_SIZE, cancellationToken).ConfigureAwait(false)) != 0)
{
theList.Add(Encoding.UTF8.GetString(buffer, 0, RECORD_SIZE));
}
return theList;
}
public async Task DoTheThingAsync_v2(List<string> theList, CancellationToken cancellationToken)
{
byte[] buffer = new byte[RECORD_SIZE];
using var fs = File.OpenRead("awesome_stuff.bin");
int read;
while ((read = await fs.ReadAsync(buffer, 0, RECORD_SIZE, cancellationToken).ConfigureAwait(false)) != 0)
{
theList.Add(Encoding.UTF8.GetString(buffer, 0, RECORD_SIZE));
}
}
}
用法:
class FunTimes
{
List<string> TheStrings;
public async Task CallingFunctionAsync_v1(CancellationToken cancellationToken)
{
this.TheStrings = await new WorkHorse().DoTheThingAsync_v1(cancellationToken).ConfigureAwait(false);
}
public Task CallingFunctionAsync_v2(CancellationToken cancellationToken)
{
this.TheStrings = new List<string>();
return new WorkHorse().DoTheThingAsync_v2(this.TheStrings, cancellationToken);
}
}
V1 是更好的方法。它是一个纯粹的黑盒函数,总是 returns 一个新列表。
V2 需要 List<string>
的初始化实例,这很容易出错。您可以轻松传递 null 并遇到问题。然后,由于这些是异步方法,您可以同时 运行 V2,并且您将在已传递的列表上出现竞争条件。