I have call an asynchronous function inside a nested loop like below
var queue = new Queue<ExchangeEmailInformation>(mailInformation);
var currentQueue = queue.ToList();
foreach (var exchangeEmailInformation in currentQueue)
{
ExchangeEmailInformation information = exchangeEmailInformation;
foreach (var queueList in exchangeEmailInformation.Attachment)
{
Attachment attachment = queueList;
information.FileName = attachment.Name;
var emailId = information.Sender.Split('@');
information.UserAlias = emailId[0];
information.FileSize = attachment.Size;
AddAttachmentAsync(information);
}
}
private static void AddAttachmentAsync(ExchangeEmailInformation information)
{
System.Threading.Tasks.Task.Factory.StartNew(
() =>
AddAttachment(information.UserAlias, information.EngagementName,
information.DocumentTransferId.ToString(), information.FileName,
information.FileSize.ToString(), information.ActivityName)).ContinueWith(
task => OnComplete(task, information), TaskContinuationOptions.None);
}
static void AddAttachment(string userAlias, string engagementName, string documentTranferId, string fileName, string fileSize,string activityName)
{
Console.Writeline(fileName);
}
In the exchange information collection has one record. In these collection there is another property called Attachment which type is AttachmentCollection which contain two attachments. After calling the method AddAttachmentAsync like above asynchronously the
results printed is
showing the second attachment only(Incorrect result).
Then i try to execute the same as Synchronously like below.
private static void AddAttachmentAsync(ExchangeEmailInformation information)
{
AddAttachment(information.UserAlias, information.EngagementName,
information.DocumentTransferId.ToString(), information.FileName,
information.FileSize.ToString(), information.ActivityName);
}
The result is
FirstAttachment.txt
SecondAttachment.txt
showing correct results as i wanted
How can i fix these issue?
information is a reference type object declared outside of the nested loop. You are passing this object to your AddAttachmentAsync method, but before waiting for it to complete (or even start processing the Task), you are already modifying information in the next iteration.
You should make a copy of information before sending it to the asynchronous method.
Edit as Marc points out this should be a new object with copied values, not just a new reference to the same object.
You have modified closure on information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With