>"吗?或者最好返回 "Task.FromResult(MyObject)"-6ren"> >"吗?或者最好返回 "Task.FromResult(MyObject)"-我的代码没问题,但我想知道哪种风格更好,你会怎么看,我正在玩异步方法。 让我建立上下文: Parallel.ForEach(xmlAnimalList, async xml => { -6ren">
gpt4 book ai didi

c# - 有效返回 "Task>"吗?或者最好返回 "Task.FromResult(MyObject)"

转载 作者:太空宇宙 更新时间:2023-11-03 19:39:40 27 4
gpt4 key购买 nike

我的代码没问题,但我想知道哪种风格更好,你会怎么看,我正在玩异步方法。

让我建立上下文:

Parallel.ForEach(xmlAnimalList, async xml =>
{
taskList.Add(await Task.FromResult(ReadAnimalXML(xml, token)));
});

这段代码使用这种方法效果很好:

public async Task<Animal> ReadAnimalXML(string filename, CancellationToken token)

在前面的示例中,您可以在 await 关键字之后看到 Task.FromResult()。 ReadAnimalXML 方法只返回一个:

return new Animal();

第二个例子是这样的:

Parallel.ForEach(xmlAnimalList, async xml =>
{
taskList.Add(await ReadAnimalXML2(xml, token));
});

这次 ReadAnimalXML2 方法返回这个:

public async Task<Task<Animal>> ReadAnimalXML2(string filename, CancellationToken token)
{
return Task.FromResult(new Animal());
}

但是!

第二种方法 ReadAnimalXML2(我觉得这很奇怪)返回一个

Task<Task<Animal>>

任务中的任务。

这就是我返回 Task.FromResult(new Animal()); 的原因否则将无法正常工作。两种方法都可以,但一种更好。您能否分享您的答案并解释原因?

感谢您进入查看问题。 编码很有趣!

public async Task<IEnumerable<Animal>> ReadXMLFromFolderAsync(string folderPath, CancellationToken token)
{
if (!Directory.Exists(folderPath))
{
return new List<Animal>();
}

List<Task<Animal>> taskList = new List<Task<Animal>>();

List<string> xmlAnimalList = Directory.GetFiles(folderPath, "*.xml").ToList();

Parallel.ForEach(xmlAnimalList, async xml =>
{
taskList.Add(await Task.FromResult(ReadAnimalXML(xml, token)));
});

return await Task.WhenAll(taskList);
}

public async Task<Animal> ReadAnimalXML(string filename, CancellationToken token)
{
XDocument document = XDocument.Load(filename);

IEnumerable<XElement> ADN = await Task.Run(() =>
document.Descendants("ADN").Where(adn => adn.Name.LocalName == "Dinosaur"), token);

//populate the animal object

return new Animal();
}

public async Task<IEnumerable<Animal>> ReadXMLFromFolderAsync2(string folderPath, CancellationToken token)
{
if (!Directory.Exists(folderPath))
{
return new List<Animal>();
}

List<Task<Animal>> taskList = new List<Task<Animal>>();

List<string> xmlAnimalList = Directory.GetFiles(folderPath, "*.xml").ToList();

Parallel.ForEach(xmlAnimalList, async xml =>
{
taskList.Add(await ReadAnimalXML2(xml, token));
});

return await Task.WhenAll(taskList);
}

public async Task<Task<Animal>> ReadAnimalXML2(string filename, CancellationToken token)
{
XDocument document = XDocument.Load(filename);

IEnumerable<XElement> ADN = await Task.Run(() => document
.Descendants("ADN")
.Where(adn => adn
.Name
.LocalName == "Dinosaur")
, token);

//populate the animal object

return Task.FromResult(new Animal());
}

最佳答案

我认为您将并行与异步混为一谈,并且两者都做错了。

如果您的方法返回 Task.FromResult ,那么它就不是异步的。如果您想要异步代码,请专注于 I/O - 例如,异步执行 I/O 以从磁盘加载文件数据,然后(同步)将其解析为 XML。

Parallel.ForEach问题更危险。首先,你不能使用 async使用 Parallel.ForEach 的方法;您的代码恰好可以工作,因为您的 async方法不是异步的。此外,您不能使用非线程安全方法,如 List<T>.Add从并行代码中。几乎所有代码都使用 Parallel.ForEach是错的。但你可能不需要 Parallel.ForEach无论如何。

如果要做异步并发,那么只需要LINQ的Select即可和 await Task.WhenAll .如果你想设置一种可以进行并行处理的管道,那么你可以使用 TPL Dataflow,或者使用 Parallel.ForEach 在异步部分完成后使用同步代码。

关于c# - 有效返回 "Task<Task<MyObject>>"吗?或者最好返回 "Task.FromResult(MyObject)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55486397/

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