如何在不遇到“多根节点”问题的情况下以异步方式编写XElement文件?

时间:2013-08-27 22:14:02

标签: c# .net asynchronous linq-to-xml xelement

我正在使用XML来模拟数据库,当用虚拟数据加载它时,我不断收到错误,告诉我有多个根元素。在打开文件后,我可以确认正在向文件写入多个根元素,但除了简单地同步调用进程之外,我所做的一切似乎都没有阻止它这样做。

以下是我的代码示例:

// 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++;
            }

        }
    }
}

对于初始加载,我只是尝试读取文件以便可以解析它,所以我限制了它的访问权限。我也确保在我解析它的时候没有人可以访问它。我会尝试这一段时间,然后继续完全拒绝请求。

然后,当尝试将信息写入文件时,我正在执行以下操作:

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);
    }
}

同样,这是异步运行的,我可以成功写入一些(15-150)记录,然后它与There are multiple root elements. Line 15, position 6.位置和行变量一起崩溃。

以下是异步调用和回调:

电话:

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);

}

回调:

private void CreateCourseComplete(IAsyncResult ar)
{
    var caller = (Func<CreateCourseRequest, CreateCourseResponse>) ar.AsyncState;
    var result = caller.EndInvoke(ar);

    if (result.Status == ResponseBase.ResponseStatus.Successful)
    {
        _successful++;
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我的猜测是,在您开始编写文件并开始重新编写文档之后,您正在捕获IOException

尝试捕获该异常并记录它。

当代码捕获异常并忽略它时,通常不是一个好兆头。