我正在以块的形式加密数据。我将每个数据块传递给一个像yay这样的任务:
private static Task<string> EncryptChunk( byte[] buffer, CryptoEngine c )
{
var tcs = new TaskCompletionSource<string>();
Task.Factory.StartNew( () =>
{
tcs.SetResult( c.Encrypt( buffer ) );
} );
return tcs.Task;
}
当我在调用此方法的代码中调试时,我可以看到它正在传递正确的块作为缓冲区参数。但是,如果我在上面的StartNew中设置断点,我看到缓冲区始终是主线程遇到的最后一个缓冲区。
我做错了什么?
答案 0 :(得分:5)
我的猜测是你重复使用相同的字节数组。将捕获参数 - 但在这种情况下,由于方法中没有任何内容捕获参数,因此它有效地捕获了引用。如果您希望能够重用原始数组(即用新数据填充它)但仍然读取任务中的旧数据,则需要复制数据。例如
private static Task<string> EncryptChunk( byte[] buffer, CryptoEngine c )
{
buffer = buffer.ToArray(); // Copy the data
var tcs = new TaskCompletionSource<string>();
Task.Factory.StartNew( () =>
{
tcs.SetResult( c.Encrypt( buffer ) );
} );
return tcs.Task;
}
顺便说一下,为什么在这里使用TaskCompletionSource
,而不仅仅是:
return Task<string>.Factory.StartNew(() => c.Encrypt(buffer));
或使用类型推断:
return Task.Factory.StartNew(() => c.Encrypt(buffer));