I'm using XML to mock up a database and, when loading it with dummy data, I keep getting an error telling me that there are multiple root elements. Upon opening the file I can confirm that multiple root elements are being written to the file, but outside of simply calling the process synchronously, nothing I've done seems to prevent it from doing so.
Here's an example of my code:
// Check to see if the file is available. If it is, parse it. Otherwise create
// a new root element. Done in the constructor since the XElement is used in
// multiple locations.
public CourseXmlWriter()
{
if (!File.Exists(Settings.Default.DataDirectory + Settings.Default.AltDb))
{
_courses = new XElement("Courses");
}
else
{
var attempts = 0;
while (attempts < MaxAttempts)
{
try
{
using (var stream = new FileStream(_dataFile,
FileMode.OpenOrCreate, FileAccess.Read, FileShare.None))
{
_courses = XElement.Load(stream);
}
break;
}
catch (IOException)
{
Thread.Sleep(1000);
attempts++;
}
}
}
}
For the initial load, I'm only trying to read the file so that it can be parsed, so I'm restricting its access. I'm also making sure that no one can access it while I'm parsing it in. I'll try this for a certain amount of time before moving on and refusing the request altogether.
Then, when attempting to write the information to a file I'm doing the following:
var attempts = 0;
while (attempts < MaxAttempts)
{
try
{
using (var stream = new FileStream(_dataFile,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
_courses.Save(stream);
}
break;
}
catch (IOException)
{
attempts++;
Thread.Sleep(1000);
}
}
Again, this is running asynchronously and I can successfully write a few (15-150) records before it crashes with the There are multiple root elements. Line 15, position 6.
Where position and line are variable.
Here are the asynchronous calls and callback:
The calls:
for (var i = 0; i < coursesToGenerate; i++)
{
var request = new CreateCourseRequest
{
Description = Path.GetRandomFileName().Replace(".", ""),
Name = Path.GetRandomFileName().Replace(".", "")
};
Func<CreateCourseRequest, CreateCourseResponse> func =
_courseAgent.CreateCourse;
func.BeginInvoke(request, CreateCourseComplete, func);
}
The callback:
private void CreateCourseComplete(IAsyncResult ar)
{
var caller = (Func<CreateCourseRequest, CreateCourseResponse>) ar.AsyncState;
var result = caller.EndInvoke(ar);
if (result.Status == ResponseBase.ResponseStatus.Successful)
{
_successful++;
}
}
Any thoughts?