c# – 完成订购任务后获取对原始任务的引用?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 完成订购任务后获取对原始任务的引用?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3081字,纯文字阅读大概需要5分钟。
内容图文
![c# – 完成订购任务后获取对原始任务的引用?](/upload/InfoBanner/zyjiaocheng/788/d733fdfb0052452aba84ef82da6fa57c.jpg)
我前一段时间问过a question关于订购List< Task< T>>>的方法了.通过它们的完成,还返回表示原始列表中的已完成任务的索引的int< Task< T>>给出.
我知道我可能不需要返回这个int来确定哪个特定的任务已经完成,并且我可以查询返回的任务以获取此信息.
作为旁注,我已经改变了方法来订购List< Task>.我最初使用Task< T>,它返回一个bool来表示Task< T>是否成功.我现在简单地抛出一个Exception的子类,它提供了有关Task失败的方式和原因的更多信息.
我对这个问题的看法来自于一个任务< int>从这个方法抛出一个异常我无法确定哪个特定的任务抛出了异常,因为我无法查询Task的原始索引的任务< int> .Result.
所以,再次,如果我可以询问任务< int> (现在只是简单的任务)从原始列表中引用的任务返回,我可以简单地比较引用.
这是现在存在的方法(对于这种方法,可以归功于original code的Servy.也可能是Jon Skeet的blog post)
public static IEnumerable<Task<int>> OrderByCompletion(IEnumerable<Task> tasks)
{
var taskList = tasks.ToList();
var taskSources = new BlockingCollection<TaskCompletionSource<int>>();
var taskSourceList = new List<TaskCompletionSource<int>>(taskList.Count);
for (int i = 0; i < taskList.Count; i++)
{
var task = taskList[i];
var newSource = new TaskCompletionSource<int>();
taskSources.Add(newSource);
taskSourceList.Add(newSource);
int index = i;
task.ContinueWith(t =>
{
var source = taskSources.Take();
if (t.IsCanceled)
source.TrySetCanceled();
else if (t.IsFaulted)
source.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCompleted)
source.TrySetResult(index);
}, CancellationToken.None, TaskContinuationOptions.PreferFairness, TaskScheduler.Default);
}
return taskSourceList.Select(tcs => tcs.Task);
}
我的第一个问题是该方法使用TaskCompletionSource< T>从参数列表中跟踪任务的TResult.看作列表< Task>>现在不返回任何值并使用Exceptions这是无用的,尽管它的使用是不可避免的,因为没有非泛化参数化的TaskCompletionSource< T>但这不是一个真正的问题,因为我可以返回一些垃圾值.
那么,对于问题本身,我可以查询任务<(未使用的返回值)>获取它跟踪的任务的引用?
从我可以告诉TaskCompletionSource< T>没有关于它正在跟踪的任务的信息.它只是“看起来像”原始任务.
是TaskCompletionSource< T>的子类的唯一选项要添加一个引用它跟踪的任务的属性,在方法中设置属性的值,然后询问该属性以获取引用?
public class TaskHoldingTaskCompletionSource<T> : TaskCompletionSource<T>
{
public Task OriginalTask { get; set; }
}
解决方法:
看看WhenAny为其类似操作解决这个问题的方式.让方法返回一个Task,其结果是它逻辑上表示完成的Task,而不是计算与该任务相同的逻辑值.这会强制调用者解开该任务,如果他们只关心任务的结果(或错误状态),但如果你不总是希望它被解包,你可以只返回整个任务.它实际上简化了代码,没有Order方法为您解开任务.
public static IEnumerable<Task<Task>> Order2(this IEnumerable<Task> tasks)
{
var taskList = tasks.ToList();
var taskSources = new BlockingCollection<TaskCompletionSource<Task>>();
var taskSourceList = new List<TaskCompletionSource<Task>>(taskList.Count);
foreach (var task in taskList)
{
var newSource = new TaskCompletionSource<Task>();
taskSources.Add(newSource);
taskSourceList.Add(newSource);
task.ContinueWith(t => taskSources.Take().TrySetResult(t),
CancellationToken.None, TaskContinuationOptions.PreferFairness, TaskScheduler.Default);
}
return taskSourceList.Select(tcs => tcs.Task);
}
内容总结
以上是互联网集市为您收集整理的c# – 完成订购任务后获取对原始任务的引用?全部内容,希望文章能够帮你解决c# – 完成订购任务后获取对原始任务的引用?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。