SQL Server Compact 3.5在后台进程中随机提供Exception

时间:2013-08-22 05:07:28

标签: c# wpf sql-server-ce

当我转移到SQL Server Compact 3.5时,它在后台运行的线程中提供异常,并且每次它给出了下面列出的不同异常。

  1. An item with the same key has already been added.

  2. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

  3. Attempted to read Data when Datareader is closed

  4. 这对我来说非常烦人,因为它突然停止我的应用程序..

    请注意,当我的后台工作程序或任务计划程序在我的应用程序中运行时,它会发生,否则应用程序正常工作。

    我不知道我做错了还是仅仅因为SQL Server Compact 3.5

    有任何帮助解决我的问题吗?

    谢谢..

    修改 使用工作单元。

    在主线程中,我从存储库中收集了200条记录

    UnitOfWork _uow;
    ObservableCollection<ViewModel> Colloection = new ObservableCollection<ViewModel>;
    ObservableCollection<ViewModel> AllColloection = new ObservableCollection<ViewModel>;
    
    public Class()
    {
       Colloection  = _uow.Contacts.Getall().Select(s=> new ViewModel(s,_uow)).Take(200).ToList();
    }
    

    在BackgroundWorker中

    AllColloection  =_uow.Contacts.Getall().Select(s=> new ViewModel(s,_uow)).ToList();
    

    收集AllCollection时,它给了我例外

    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

    我想要显示200条记录,当用户点击下一条时,我将从Allcolloection收集下200条记录。

1 个答案:

答案 0 :(得分:2)

看起来你在不同的线程之间共享ADO .NET对象(连接,命令,读取器等)而没有同步。

在代码中添加一些同步:

private readonly _uowLock;

public Class()
{
    _uowLock = new object();

    // run any background threads

    // loading data in main thread
    LoadCollection();
}

private void LoadCollection()
{
    // obtain lock
    lock (_uowLock)
    {
        Collection  = _uow.Contacts.Getall().Select(s=> new ViewModel(s,_uow)).Take(200).ToList();
    }
}

// this should be called from background worker
private void LoadAllCollection()
{
    // obtain lock
    lock (_uowLock)
    {
        AllColloection  =_uow.Contacts.Getall().Select(s=> new ViewModel(s,_uow)).ToList();
    }
}

,或者不在线程之间共享ADO .NET对象 - 它们不是线程安全的:

public Class()
{
    // run any background threads

    // loading data in main thread
    LoadCollection();
}

private void LoadCollection()
{
    Collection  = new UnitOfWork().Contacts.Getall().Select(s=> new ViewModel(s,_uow)).Take(200).ToList();
}

// this should be called from background worker
private void LoadAllCollection()
{
    AllColloection  = new UnitOfWork().Contacts.Getall().Select(s=> new ViewModel(s,_uow)).ToList();
}