我最近asked a question关于清理一些代码的可能性,代码是等待Task
中的每个List<Task<T>>
完成,但取消所有Task
如果一个人返回了一些虚假的价值。
名为Servy quickly produced a method的用户,在完成时间内雄辩地命名List<Task<T>>
。在仔细阅读了答案之后,我认为/我认为/理解这个方法。然后我开始使用该方法,但很快就意识到了问题。我需要能够在他们完成时识别Task
。但是Servy建议的Order
方法没有办法做到这一点(因为我无法将Order
返回的任务延续与我最初提供的List<Task<>>
进行比较。
所以我去更改方法以返回Tuple<T, int>
,其中int
表示提供的参数中Task
的原始索引。
public static IEnumerable<Task<Tuple<T, int>>> OrderByCompletion<T>(IEnumerable<Task<T>> tasks)
{
var taskList = tasks.ToList();
var taskSources = new BlockingCollection<TaskCompletionSource<Tuple<T, int>>>();
var taskSourceList = new List<TaskCompletionSource<Tuple<T, int>>>(taskList.Count);
for (int i = 0; i < taskList.Count; i++)
{
var task = taskList[i];
var newSource = new TaskCompletionSource<Tuple<T, int>>();
taskSources.Add(newSource);
taskSourceList.Add(newSource);
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(new Tuple<T, int>(t.Result, i));
}, CancellationToken.None, TaskContinuationOptions.PreferFairness, TaskScheduler.Default);
}
return taskSourceList.Select(tcs => tcs.Task);
}
// Usage
foreach(var task in myTaskList.OrderByCompletion())
Tuple<Boolean, int> result = await task;
我面临的问题是,Tuple
返回的索引似乎始终等于传递给Count
的{{1}}的{{1}},无论是返回任务的顺序。
我认为由于这个问题我不能完全理解这种方法是如何起作用的,尽管看起来它应该可以正常工作。
任何人都可以解释这个问题并提供解决方案吗?
答案 0 :(得分:2)
这是因为您在OMX_ERRORTYPE OMX::OnFillBufferDone(
node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
ALOGV("OnFillBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::FILL_BUFFER_DONE;
msg.node = node;
msg.u.extended_buffer_data.buffer = buffer;
msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
msg.u.extended_buffer_data.flags = pBuffer->nFlags;
msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
//dump date code
if(pBuffer->nFilledLen>0) {
FILE *fp=NULL;
fp=fopen("/data/video.yuv","a+");
if(fp) {
fwrite((unsigned char *)pBuffer->pBuffer,1,pBuffer->nFilledLen,fp);
fclose(fp);
}else {
ALOGE(" catch data is failure");
}/*...*/}}}
内使用i
变量。
但是,当您创建Action<>
时,不会执行此操作的代码,但是当任务完成时,变量Action
的值为i
(当{{1}时) } loop finished)。
您只需向taskList.Count
添加额外的变量即可解决您的问题:
for
您可以阅读此question/answers了解详情。