我正在尝试声明具有特定数量项的Dictionary<Task>
,我尝试过:
private Dictionary<Task, CancellationToken> bots =
new Dictionary<Task, CancellationToken>(new Task[9], new CancellationToken[9]);
这将返回以下错误:
您不能从“ System.Threading.Tasks.Task []”转换为“ System.Collections.Generic.IDictionary”
如果我在List
中这样做,那么一切正常:
private List<Task> bots = new List<Task>(new Task[9]);
答案 0 :(得分:1)
错误显示您正在尝试不存在的东西。
其中一个重写词典构造函数接受
public Dictionary(IDictionary<TKey, TValue> dictionary);
public Dictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer);
您提供的参数都不正确。 您输入的第一个输入是Task [],第二个输入是CancellationToken []
您应该创建一个IDictionary实现,通常是一个Dictionary,然后将其传递给它。
var example1Original = new Dictionary<Task, CancellationToken>();
example1Original.Add(new Task(DoWork), new CancellationToken());
example1Original.Add(new Task(DoWork), new CancellationToken());
// and more (This procedure can be shorten using a loop)
var example1Result = new Dictionary<Task, CancellationToken>(example1Original);
如您所见,我们已成功将变量传递到Dictionary构造函数中,这是可能的,因为Dictionary实现了IDictionary,如我们在此处看到的
但是最后一行实际上是多余的,因为是的,我们可以通过它,但是我们不需要。因为我们填充的example1Original已经是我们要使用的字典。
所以这引出了一个问题,为什么Dictionary构造函数首先将其包含。这就引出了我们最初的说法,即IDictionary可以具有可以通过的多种实现。
这里有一些IDictionary实现
(图片是使用ILSpy从mscorlib.dll拍摄的)
实际上,您的问题是,我该如何用Task和Cancellation令牌的新实例填充我的Dictionary。
这可以通过以下方式完成:
我们将要使用的功能
Enumerable.ToDictionary-由于IDictionary本身实现IEnumerable,因此我们可以使用以下ToDictionary扩展方法
System.Linq 名称空间中的
扩展方法
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
如果我们将使用这些功能,我们可以构建以下内容以生成我们的字典。
var kvpOfTaskCancellation = Enumerable.Range(0, 9) // Generates Enumerable integers sequence.
.Select(i => new KeyValuePair<Task, CancellationToken>(new Task(DoWork), new CancellationToken())) // Iterating and projecting every elements inside the previous generated sequence.
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Mapping each iteration from the previous line KeyValuePair objects to the Dictionary Key and Value.
还可以缩短为以下内容
var kvpOfTaskCancellation2 = Enumerable.Range(0, 9)
.ToDictionary(kvp => new Task(DoWork), kvp => new CancellationToken());
如果您想要一个新的“任务和取消”令牌,这一切都可以。
但是但是,如果您已经有大量的Tasks和CancellationTokens集合,并且想要从中生成一个Dictionary,那么您可以执行以下操作:
var tasks = new Task[3];
// I'm assuming the tasks already been populated
tasks.ToDictionary(kvp => kvp, kvp => new CancellationToken());
但是如果您还具有CancellationToken数组,则可以使用以下内容:
var tasks = new Task[3];
var cancellationsTokens = new CancellationToken[9];
// I'm assuming tasks and cancellationToken array already been filled.
Enumerable.Range(0, tasks.Length)
.Select(i => new KeyValuePair<Task, CancellationToken>(tasks[i], cancellationsTokens[i]))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
答案 1 :(得分:0)
Task
的未初始化数组仅包含null元素,并且不能将null作为字典项的键,但是通常,如果您已初始化数组,则可以使用Linq将字典与这些数组配合使用:
var dictionary = (from token in new CancellationToken[9]
from task in initializedTaskArray
select (task, token)
)
.ToDictionary(x => x.task, x => x.token);
答案 2 :(得分:-1)
您需要执行以下操作:
private Dictionary<Task, CancellationToken> bots = new Dictionary<Task, CancellationToken>() {
{ new Task(), new CancellationToken() },
{ new Task(), new CancellationToken() },
...
}