System.UnauthorizedAccessException 在嵌套流调用中
System.UnauthorizedAccessException in nested Stream calls
我在这个函数中得到 System.UnauthorizedAccessException
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;
}
}
在 for
循环中调用 5-10 次而没有 Sleep
。我的 for 循环看起来像这样:
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])));
}
}
我相信这种情况正在发生,因为我正在处理 xml 非常快的写入和读取。除了添加 Sleeps
之外,这里还有解决方法吗?
XMLDisplaySignals
看起来像这样处理和 xml 写
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。如果我在 for 循环中添加 300MS 的睡眠,问题就解决了。然而,众所周知,睡眠不是解决办法。
你是对的。睡眠不是解决方案,因为您永远无法确定手术需要多长时间。
您需要在使用之前锁定您的资源(即在您的 XMLDisplaySignals
方法中调用 OpenStreamForReadAsync
之前),以便在资源从之前的 [=20= 中释放之前不会尝试该操作].
This page 解释了如何使用 AsyncSemaphore
来达到这个目的。
我在这个函数中得到 System.UnauthorizedAccessException
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;
}
}
在 for
循环中调用 5-10 次而没有 Sleep
。我的 for 循环看起来像这样:
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])));
}
}
我相信这种情况正在发生,因为我正在处理 xml 非常快的写入和读取。除了添加 Sleeps
之外,这里还有解决方法吗?
XMLDisplaySignals
看起来像这样处理和 xml 写
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。如果我在 for 循环中添加 300MS 的睡眠,问题就解决了。然而,众所周知,睡眠不是解决办法。
你是对的。睡眠不是解决方案,因为您永远无法确定手术需要多长时间。
您需要在使用之前锁定您的资源(即在您的 XMLDisplaySignals
方法中调用 OpenStreamForReadAsync
之前),以便在资源从之前的 [=20= 中释放之前不会尝试该操作].
This page 解释了如何使用 AsyncSemaphore
来达到这个目的。