I'm encrypting data in chunks. I'm passing each chunk of data to a Task like 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.T开发者_开发技巧ask;
}
As I debug in the code that calls this method I can see that it's passing proper chunks as the buffer parameter. If I set a breakpoint inside StartNew above, however, I see that the buffer is always the last buffer encountered by the main thread.
What am I doing wrong?
My guess is that you're reusing the same byte array. The parameter will be captured - but in this case as nothing in your method captures the parameter, it's effectively capturing the reference. If you want to be able to reuse the original array (i.e. populate it with new data) but still read the old data within the task, you need to make a copy of the data. e.g.
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;
}
As an aside, why are you using TaskCompletionSource
here, instead of just:
return Task<string>.Factory.StartNew(() => c.Encrypt(buffer));
or using type inference:
return Task.Factory.StartNew(() => c.Encrypt(buffer));
精彩评论