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
- SecondAttachment.txt
- SecondAttachment.txt.
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?
In the first line of the second foreach(), you must make a copy of ‘information’ and pass the copy to AddAttachmentAsync. (That is, a copy of all the data – not just a copy of the object reference.)
What’s happening is that the ‘information’ object you’re passing to AddAttachmentAsync() is being changed before AddAttachmentAsync() has returned.
In general, when designing classes such as ExchangeEmailInformation that are used for multithreaded stuff, you should make them immutable – then it’s impossible for this particular kind of thing to happen. (In my opinion, you should make ALL POD (“plain old data”) classes immutable.)