async和wait,同时将元素添加到List<;T>;
本文关键字:List gt lt 添加 元素 wait async | 更新日期: 2023-09-27 18:25:31
我编写了一个方法,它从许多来源向List添加元素。见下文:
public static async Task<List<SearchingItem>> GetItemsToSelect()
{
List<SearchingItem> searchingItems = new List<SearchingItem>();
foreach (Place place in await GetPlaces())
{
searchingItems.Add(new SearchingItem() {
IdFromRealModel=place.Id, NameToDisplay=place.FullName,
ExtraInformation=place.Name, TypeOfSearchingItem=TypeOfSearchingItem.PLACE });
}
foreach (Group group in await GetGroups())
{
searchingItems.Add(new SearchingItem()
{
IdFromRealModel = group.Id, NameToDisplay = group.Name,
ExtraInformation = group.TypeName, TypeOfSearchingItem = TypeOfSearchingItem.GROUP
});
}
return searchingItems;
}
我测试了这个方法,效果很好。我认为它是有效的,因为GetPlaces方法返回160个元素,GetGroups返回3000个元素。但是,我想知道如果这些方法同时返回元素,它是否会起作用。我应该锁定列表搜索项目吗?
谢谢你的建议。
您的项目没有同时运行,您启动GetPlaces()
,停止并等待GetPlaces()
结果,然后进入第一个循环。然后启动GetGroups()
,停止并等待GetGroups()
结果,然后进入第二个循环。循环不是并发的,所以添加它们时不需要锁定。
然而,如果您已经注意到您的两个异步方法也不是并发的,那么您可以很容易地修改您的程序使其成为并发的。
public static async Task<List<SearchingItem>> GetItemsToSelect()
{
List<SearchingItem> searchingItems = new List<SearchingItem>();
var getPlacesTask = GetPlaces();
var getGroupsTask = GetGroups();
foreach (Place place in await getPlacesTask)
{
searchingItems.Add(new SearchingItem() {
IdFromRealModel=place.Id, NameToDisplay=place.FullName,
ExtraInformation=place.Name, TypeOfSearchingItem=TypeOfSearchingItem.PLACE });
}
foreach (Group group in await getGroupsTask)
{
searchingItems.Add(new SearchingItem()
{
IdFromRealModel = group.Id, NameToDisplay = group.Name,
ExtraInformation = group.TypeName, TypeOfSearchingItem = TypeOfSearchingItem.GROUP
});
}
return searchingItems;
}
这将启动GetPlaces()
,启动GetGroups()
,停止并等待GetPlaces()
的结果,然后进入第一个循环,停止并等候GetGroups()
的结果,再进入第二个循环。
这两个循环仍然不是并发的,但您的两个可等待的方法是,这可能会给您带来一些性能提升。我怀疑你是否会从并发循环中得到任何好处,它们似乎只是在构建模型,而使其线程安全的开销是不值得的,因为所做的工作很少。
如果你真的想尝试并使其更加并行(但我怀疑你会看到很多好处),那就是使用PLINQ来构建你的模型。
public static async Task<List<SearchingItem>> GetItemsToSelect()
{
var getPlacesTask = GetPlaces();
var getGroupsTask = GetGroups();
var places = await getPlacesTask;
//Just make the initial list from the LINQ object.
List<SearchingItem> searchingItems = places.AsParallel().Select(place=>
new SearchingItem() {
IdFromRealModel=place.Id, NameToDisplay=place.FullName,
ExtraInformation=place.Name, TypeOfSearchingItem=TypeOfSearchingItem.PLACE
}).ToList();
var groups = await getGroupsTask;
//build up a PLINQ IEnumerable
var groupSearchItems = groups.AsParallel().Select(group=>
new SearchingItem()
{
IdFromRealModel = group.Id, NameToDisplay = group.Name,
ExtraInformation = group.TypeName, TypeOfSearchingItem = TypeOfSearchingItem.GROUP
});
//The building of the IEnumerable was parallel but the adding is serial.
searchingItems.AddRange(groupSearchItems);
return searchingItems;
}