使用Task.WhenAny与字典

我目前正在编写一个服务,它将为他在数据库中找到的每个“等待进程”请求创建Task。使用Task.WhenAny与字典

该过程可能很长,并且我希望服务在每次必须取消任务时检查它,如果是这种情况我想用令牌取消任务。所以我需要存储链接到任务的请求的ID。

我在想,我有我的字典静态类如下:

public static Dictionary<Int32, Task<Int32>> _tasks = new Dictionary<int, Task<int>>(); 

,我不知道这是否是更好的解决方案存在,但它仍然是一个工作,我认为。

现在我想做一个Task.WhenAny(..)来知道其中一个是否结束。问题是Task.WhenAny(..)接受一个数组,但不是一个Dictionary。我没有看到任何关于将字典传递给WhenAny的任何事情,并且在开始处理很长的整个过程之前,我希望为我的工作流程的每个关键点提供解决方案。我可以获得字典值的列表,但我可能会丢失id链接。所以我不知道该怎么办?

有没有解决方案?我不想重新创建自己的“自己的”WhenAny,我甚至不知道是否有可能,但我认为我只能解析每一行的状态。但如果这是唯一的选择,我会的。

我也打开这样一个事实,即以这种方式存储请求的ID不是一个好办法,在这种情况下,我可以接受任何其他建议。


编辑:CODE ACORDING进行答辩 我使用此代码,这似乎是工作结束。现在我将测试更复杂的任务,而不仅仅是一个文件写入! :)

public static class Worker 

{

public static List<Task<Int32>> m_tasks = new List<Task<Int32>>();

public static Dictionary<Int32, CancellationTokenSource> m_cancellationTokenSources = new Dictionary<int, CancellationTokenSource>();

public static Int32 _testId = 1;

public static void run()

{

//Clean

Cleaner.CleanUploads();

Cleaner.CleanDownloads();

#region thread watching

if (m_tasks.Count > 0)

{

#region thread must be cancel

//Cancel thread

List<Task<Int32>> _removeTemp = new List<Task<Int32>>();

foreach (Task<Int32> _task in m_tasks)

{

if (DbWorker.mustBeCancel((Int32)_task.AsyncState))

{

m_cancellationTokenSources[(Int32)_task.AsyncState].Cancel();

//Cancellation actions

//task must be remove

_removeTemp.Add(_task);

}

}

foreach(Task<Int32> _taskToRemove in _removeTemp)

{

m_tasks.Remove(_taskToRemove);

}

#endregion

#region Conversion lookup

// Get conversion if any

// Create task

CancellationTokenSource _srcCancel = new CancellationTokenSource();

m_cancellationTokenSources.Add(_testId, _srcCancel);

m_tasks.Add(Task.Factory.StartNew(_testId => testRunner<Int32>((Int32)_testId), _testId, _srcCancel.Token));

_testId++;

// Attach task

#endregion

}

#endregion

else

{

CancellationTokenSource _srcCancel = new CancellationTokenSource();

m_cancellationTokenSources.Add(_testId, _srcCancel);

m_tasks.Add(Task.Factory.StartNew(_testId => testRunner<Int32>((Int32)_testId), _testId, _srcCancel.Token));

_testId++;

}

}

internal static void WaitAll()

{

Task.WaitAll(m_tasks.ToArray());

}

public static Int32 testRunner<T>(T _id)

{

for (Int32 i = 0; i <= 1000000; i++)

{

File.AppendAllText(@"C:\TestTemp\" + _id, i.ToString());

}

return 2;

}

}

回答:

有一个Task.WhenAny that takes an IEnumerable<Task>和one that takes IEnumerable<Task<T>>,所以你应该只能够使用:

var winner = Task.WhenAny(theDictionary.Values); 

回答:

Task.WhenAny返回值是:代表

任务完成提供的任务之一。 返回任务的结果是已完成的任务。

从docs。

所以基本上你可以传递给它的字典值和等待它,你会得到,这是完成了任务,从这里很容易附着在该任务是使用一些LINQ ID:

var task = await Task.WhenAny(_tasks.Values); 

var id = _tasks.Single(pair => pair.Value == task).Key;

以上是 使用Task.WhenAny与字典 的全部内容, 来源链接: utcz.com/qa/262714.html

回到顶部