I am getting System.UnauthorizedAccessException
in this function
public static async Task<IEnumerable<XElement>> XMLDisplaySignals()
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await storageFolder.GetFileAsync("sFile.xml");
XDocument doc;
try
{
using (var stream = await file.OpenStreamForReadAsync())
{
doc = XDocument.Load(stream);
IEnumerable<XElement> signals = doc.Descendants("signals");
return signals;
}
}
catch(Exception ex)
{
Debug.WriteLine(ex.StackTrace);
return null;
}
}
when called in a a for
loop 5-10 times without a Sleep
. My for loop looks like this:
for (int j = 0; j < iItems[0].Count; j++)
{
IEnumerable<XElement> signals = await SampleDataSource.XMLDisplaySignals();
if (signals != null && signals.Descendants("signal").Any())
{
if(!signals.Descendants("signal").Any(x => x.Element("title").Value == iItems[0][j]))
{
Debug.WriteLine("Adding: " + iItems[0][j]);
await SampleDataSource.XMLAddXElement(new XElement("signal", new XElement("title", iItems[0][j]), new XElement("body", iItems[1][j])));
}
else
{
Debug.WriteLine("Already in");
}
}
else
{
//handle the bug hardcore
await SampleDataSource.XMLAddXElement(new XElement("signal", new XElement("title", iItems[0][j]), new XElement("body", iItems[1][j])));
}
}
I believe this is happening because I am handling xml writes and reads very fast. Is there a workaround here besides adding Sleeps
?
XMLDisplaySignals
looks like this and handles and xml write
public static async Task XMLAddXElement(XElement element)
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await storageFolder.GetFileAsync("sFile.xml");
XDocument doc;
try
{
using (var stream = await file.OpenStreamForReadAsync())
{
doc = XDocument.Load(stream);
var signals = doc.Descendants("signals").Single();
signals.Add(element);
using (var stream2 = await file.OpenStreamForWriteAsync())
{
stream2.SetLength(0);
doc.Save(stream2);
}
}
}
catch(Exception ex)
{
//Debug.WriteLine(ex.StackTrace);
}
}
P.S. if I add a sleep of 300MS in the for loop, the problem is solved. However as we all know sleep is not a solution.
You are right. Sleep is not a solution because you can never be sure how long the operation will take.
You need to lock your resource before using it (i.e. before calling OpenStreamForReadAsync
in your XMLDisplaySignals
method) so the operation is not attempted before the resource is released from the previous run.
This page explains how to use AsyncSemaphore
for that purpose.