我有一个对象列表,我需要在这个列表中得到一个对象,它最好地标识一个特定的项,并在该对象中添加该项。
List<Category> endpoints = new List<Category>();
endpoints = await GetRelatedCategoriesAsync(pp);
float catScore = 0;
Category categoryHit = new Category();
// THIS LOOP SHOULD BE ASYNCHRONOUS
foreach (Category cat in endpoints)
{
SentenceSimilarity similarity = new SentenceSimilarity();
string phrase = cat.Keywords.Replace("|", " ");
float score = similarity.GetScore(phrase, string.IsNullOrEmpty(wholeWord) ? "" : wholeWord);
if (catScore == 0)
{
catScore = score;
categoryHit = cat;
}
else
{
if (catScore > score)
{
// Do something here
}
else
{
catScore = score;
categoryHit = cat;
}
}
}当GetRelatedCategoriesAsync返回100多条记录而处理时间太长时,问题就会发生,我在异步处理时遇到了问题,所以我暂时做的是,如果相关类别至少到达21个对象,我就会对该项进行“分类”。
我如何使这个异步,我也读过关于SemaphoreSlim,但我不确定这是否是我需要使用的。
UPDATE在试用Yuval Itzchakov建议后,我得到以下错误:
at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
at System.Linq.Parallel.SpoolingTask.SpoolStopAndGo[TInputOutput,TIgnoreKey](QueryTaskGroupState groupState, PartitionedStream`2 partitions, SynchronousChannel`1[] channels, TaskScheduler taskScheduler)
at System.Linq.Parallel.DefaultMergeHelper`2.System.Linq.Parallel.IMergeHelper<TInputOutput>.Execute()
at System.Linq.Parallel.MergeExecutor`1.Execute()
at System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
at System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
at System.Linq.Parallel.AssociativeAggregationOperator`3.WrapPartitionedStream[TKey](PartitionedStream`2 inputStream, IPartitionedStreamRecipient`1 recipient, Boolean preferStriping, QuerySettings settings)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.QueryOperator`1.GetOpenedEnumerator(Nullable`1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
at System.Linq.Parallel.QueryOpeningEnumerator`1.OpenQuery()
at System.Linq.Parallel.QueryOpeningEnumerator`1.MoveNext()
at System.Linq.Parallel.AssociativeAggregationOperator`3.Aggregate()
at System.Linq.AggregationMinMaxHelpers`1.Reduce(IEnumerable`1 source, Int32 sign)
at System.Linq.AggregationMinMaxHelpers`1.ReduceMax(IEnumerable`1 source)
at System.Linq.ParallelEnumerable.Max[TSource](ParallelQuery`1 source)
at System.Linq.ParallelEnumerable.Max[TSource,TResult](ParallelQuery`1 source, Func`2 selector)
at Scraper.UskoopScraper.<GetCategoryIdAsync>d__80.MoveNext() in d:\projects\\\file.cs:line 1001发布于 2015-08-12 11:47:28
我不确定我是否理解算法的确切要求,但是看起来你似乎在试图从所有的类别中找到最大的需求。
您可以做的是定义一个实现IComparable<T>的类,并通过调用AsParallel使用PLINQ (并行LINQ),并使用它的扩展方法ParallelEnumerable.Max。它看起来类似于这样:
public class CategoryResult : IComparable<CategoryResult>
{
public Category Category { get; set; }
public int Score { get; set; }
public int CompareTo(CategoryResult other)
{
int comparison = 0;
if (this.Score == other.Score)
{
comparison = 0;
}
else if (this.Score > other.Score)
{
comparison = 1;
}
else if (this.Score < other.Score)
{
comparison = -1;
}
return comparison;
}
}然后你会像这样调用你的方法:
var maxCategoryResult = list.AsParallel().Max(cat =>
{
SentenceSimilarity similarity = new SentenceSimilarity();
string phrase = cat.Keywords.Replace("|", " ");
float score = similarity.GetScore(
phrase, string.IsNullOrEmpty(wholeWord) ? "" : wholeWord);
CategoryResult catResult = null;
if (catScore == 0 || catScore < score)
{
catResult = new CategoryResult
{
Category = cat,
Score = score
}
}
else
{
// Create different category?
}
return catResult;
}https://stackoverflow.com/questions/31963136
复制相似问题