C#SQLite Windows CE“内存不足异常”。

时间:2013-12-10 17:31:57

标签: c# multithreading sqlite compact-framework

所以我一直有一个问题,我收到一个错误,说明我已经没有记忆了。我有一个主线程和一个工作线程,它使用一个名为SqlLiteAssetCommands.cs的文件,其中包含一些命令,如下所示。

    Database newConnection;
    /// <summary>
    /// Open connection return the SQLlight command
    /// </summary>
    /// <returns></returns>
    private SQLiteCommand openConnection()
    {
        newConnection = new Database();
        SQLiteCommand command = new SQLiteCommand();
        try
        {
            newConnection.OpenConnection();
            command = newConnection.Connection.CreateCommand();
        }
        catch (Exception e)
        {
            log.Error("Could not open connection.", e);
        }
        return command;
    }

    /// <summary>
    /// Close connection to the local database.
    /// </summary>
    private void closeConnection()
    {
        try
        {
            newConnection.CloseConnection();
        }
        catch (Exception e)
        {
            log.Error("Could not close the connection.", e);
        }
    }

    /// <summary>
    /// Creates a transaction.
    /// </summary>
    /// <returns>Returns the new transaction that is created.</returns>
    private SQLiteTransaction getTransaction()
    {
        SQLiteTransaction sqlTransaction = null;
        try
        {
            sqlTransaction = newConnection.Connection.BeginTransaction();
        }
        catch (Exception e)
        {
            log.Error("Could not get sqlTransaction.", e);
        }
        return sqlTransaction;
    }

    #region Asset Database commands

    /// <summary>
    /// Delete all rows from sqlite database.
    /// </summary>
    /// <returns>Returns "Completed" if successful.</returns>
    public String deleteAllRows()
    {
        SQLiteCommand command = openConnection();
        String status = null;
        using (SQLiteTransaction sqlTransaction = getTransaction())
        {
            try
            {
                command.CommandText = @"DELETE FROM Asset";
                using (SQLiteDataReader reader = command.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        reader.Read();
                    }
                    reader.Close();
                }
                status = "Completed";
                sqlTransaction.Commit();
            }
            catch (Exception e)
            {
                log.Error("Could not delete all assets.", e);
            }
        }
        closeConnection();
        return status;
    }

所以我的开放连接是从一个名为Database.cs的不同文件中调用的,并且在打开的函数中发现错误,说明我内存不足。我不知道我需要做些什么来防止这种情况发生,因为我无法强制发生错误。这次发生在我试图强制显示错误的时候,所以我可以进行屏幕拍摄,最后厌倦了尝试并等待而没有做任何事情。然后它刚刚发生,因为我的工作线程。

    public SQLiteConnection Connection = new SQLiteConnection();
    // Define a static logger variable so that it references the name of your class
    private static readonly ILog log = LogManager.GetLogger(typeof(Database));

    // Try to open a connection to the sqlLight database.
    public void OpenConnection()
    {
        try
        {
            Connection = new SQLiteConnection("Data Source=" + Utilities.Global.SqlLiteDB);
            Connection.Open();
        }
        catch (Exception eErr)
        {
            log.Error("Error connecting to database.", eErr);
            MessageBox.Show("Error connecting to database.", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
        }
    }
    // Close the database connection.
    public void CloseConnection()
    {
        Connection.Close();
    }
}

enter image description here

我可以采取任何措施来解决这个问题或改进我的代码。

以下是我的工作线程的代码,因为这可能是问题的根本原因。

class AssettoServerThread
{
    // Define a static logger variable so that it references the name of your class
    private static readonly ILog log = LogManager.GetLogger(typeof(AssettoServerThread));

    WebServicesSyncAsset syncAsset = new WebServicesSyncAsset();
    SqlLightAssetCommands assetToSql = new SqlLightAssetCommands();


    /////////////////////// Variables //////////
    private volatile bool _shouldStop = false;

    // SINGLETON ///////////////////////////////
    private static AssettoServerThread instance = null;

    public static AssettoServerThread GetInstance()
    {
        if (instance == null)
            instance = new AssettoServerThread();

        return instance;
    }
    // /////////////////////////////////////////

    // this variable will hold the condition of ServicesAvailable set by the worker thread
    private bool areServicesAvailable = false;

    private bool AreServicesAvailable
    {
        get { return areServicesAvailable; }
        set { areServicesAvailable = value; }
    }

    // This method will be called when the thread is stopped. 
    public void RequestStop()
    {
        _shouldStop = true;
    }

    // Create a worker thread and then check if the webservices are available.
    // If available then set ServicesAvailable to true and begin sending updated assets to the server.
    public void DoThreading()
    {
        // Continuous loop
        while (!_shouldStop)
        {
            try
            {
                // Creates an HttpWebRequest for the specified URL.
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfigSettings.serverIP);
                // Set some reasonable limits on resources used by this request
                request.KeepAlive = false;
                request.ProtocolVersion = HttpVersion.Version10;
                // Sends the HttpWebRequest and waits for a response.
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    //request.Abort();
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        areServicesAvailable = true;
                    }
                    // Releases the resources of the response.
                    response.Close();
                }
            }
            catch (WebException ex)
            {
                areServicesAvailable = false;
                log.Info("Website is currently not accessible. Therefore the services are not accessible.", ex);
            }
            catch (Exception ex)
            {
                areServicesAvailable = false;
                log.Info("Website is currently not accessible. Therefore the services are not accessible.", ex);
            }

            // If the webservices are available then run else sleep for 30 seconds.
            if (AreServicesAvailable)
            {
                try
                {
                    assetToSql.AddAssetsToServer();
                    Thread.Sleep(2000);
                }
                catch (Exception e)
                {
                    log.Error("Could not add asset to server.", e);
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

  

然后它刚刚发生,因为我的工作线程。

您的线程代码可能是相关的。

答案 1 :(得分:0)

我最终做的不是使用两个线程而是将其组成一个工作线程并确保它永远不会重叠。我还在我的SQLlite数据库中添加了一个连接池。我还更改了项目中的图像并删除了所有不必要的图像以节省空间。我不知道是什么修复它但这对我有用。