简体   繁体   English

运行Visual Studio 2012单元测试框架测试后,SQLite.Interop.dll被锁定

[英]SQLite.Interop.dll locked after running Visual Studio 2012 Unit Test Framework tests

  • Visual Studio 2012 Visual Studio 2012
  • SQLite 1.0.82.0 (from nuget) SQLite 1.0.82.0(来自nuget)

I am trying to use the "Run All" command in the "Test Explorer" The following error happens after you run the test once ... after that it will not build anymore, until you restart visual studio 我试图在“测试资源管理器”中使用“全部运行”命令在运行测试一次之后发生以下错误...之后它将不再构建,直到您重新启动visual studio

Here is the build error 这是构建错误

The Process cannot access the file 'SQLite.Interop.dll' because it is being used by another process 进程无法访问文件'SQLite.Interop.dll',因为它正被另一个进程使用

here is the code 这是代码

using System.Data.SQLite;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Test.Sqlite
{
    [TestClass]
    public class Test_Sqlite_Locking
    {
        [TestMethod]
        public void can_create_table()
        {
            using(var fact = new SQLiteFactory())            
            using (var conn = fact.CreateConnection())
            {
                conn.ConnectionString = "Data Source=:memory:;Version=3;New=True;";
                conn.Open();
                //conn.Close();                
            }

            //SQLiteConnection.ClearAllPools();
            //GC.Collect();
        }
    }
}

I have tried, closing connection, calling ClearAllPools, GC.Collect, and creating the SQLiteConnection directly (instead of the Factory) ... still same issue 我试过,关闭连接,调用ClearAllPools,GC.Collect,直接创建SQLiteConnection(而不是Factory)...仍然是同样的问题

This DOES work if you DEBUG ALL TESTS ... but it is when you just Run the tests that this seems to lock it up 如果您调试所有测试,这可以工作......但是当您运行测试时,它似乎将其锁定

I could not find that option in VS2012 (at least not for standard unit tests), therefore I came up with another solution: 我在VS2012中找不到该选项(至少不能用于标准单元测试),因此我提出了另一种解决方案:

The problem you are facing comes from the fact that the unit test runner remains loaded so that repeated test runs are faster. 您遇到的问题来自于单元测试运行器仍然加载,以便重复测试运行更快。 Since SQLite.Interop.dll will probably not change too often, I changed the CopyToOutputDirectory option to PreserveNewest rather than the default Always . 由于SQLite.Interop.dll可能不会经常更改,我将CopyToOutputDirectory选项更改为PreserveNewest而不是默认的Always

You can do this by opening the properties (F4) view and selecting the SQLite.Interop.dll file in your solution. 您可以通过打开属性(F4)视图并在解决方案中选择SQLite.Interop.dll文件来执行SQLite.Interop.dll操作。 The only time this will probably still lock up is when you upgrade to a newer version of SQLite and restarting VS2012 then works OK for me. 这可能仍会锁定的唯一一次是当您升级到更新版本的SQLite并重新启动VS2012时,对我来说工作正常。

I worked around this by using the following as a pre-build event on the affected test projects: 我通过使用以下作为受影响的测试项目的预构建事件来解决这个问题:

for 64-bit: 对于64位:

taskkill /F /IM vstest.executionengine.exe /FI "MEMUSAGE gt 1"

or for 32-bit: 或32位:

taskkill /F /IM vstest.executionengine.x86.exe /FI "MEMUSAGE gt 1"

This silently kills the execution engine before building the test project. 在构建测试项目之前,这会默默地杀死执行引擎。 The /FI "MEMUSAGE gt 1" stops the command (and therefore the build) from failing if the execution engine isn't running. 如果执行引擎未运行, /FI "MEMUSAGE gt 1"停止命令(因此构建)失败。

Try this: 尝试这个:

  • In VS.NET, click on Tools \\ Options 在VS.NET中,单击Tools \\ Options
  • When the dialog appears, click on "Test Tools" 出现对话框时,单击“测试工具”
  • Click on "Test Execution" 点击“测试执行”
  • Uncheck the box "Keep test execution engine running between tests" 取消选中“让测试执行引擎在测试之间运行”框
  • Click OK and restart VS.NET 单击确定,然后重新启动VS.NET

You should be able run SQLite based tests now without having to restart. 您应该能够立即运行基于SQLite的测试,而无需重新启动。

In Visual Studio 2013 - Go to "Test > Test Settings > keep Test Execution Engine Runing" and uncheck it! 在Visual Studio 2013中 - 转到“测试>测试设置>保持测试执行引擎运行”并取消选中它! Works for me. 适合我。

The workaround provided by Philipp Aumayr (set CopyToOutputDirectory option to PreserveNewest rather than the default Always ) works for most scenarios, but not all, unfortunately. Philipp Aumayr提供解决方法 (将CopyToOutputDirectory选项设置为PreserveNewest而不是默认的Always )适用于大多数情况,但不幸的是并非全部。 As other questions on SO point out, the fact that vstest.executionengine does not terminate is a common issue in VS2012 - worse, Microsoft developers treat this as a feature and by design . 正如SO上的其他问题所指出的那样, vstest.executionengine不会终止这一事实是vstest.executionengine中的一个常见问题 - 更糟糕的是,微软开发人员将此视为一种功能而非设计 The option to prevent this behavior existed in VS2010 but has been removed in VS2012. VS2010中存在防止此行为的选项,但已在VS2012中删除。

If you too have a problem with this "improvement" then please vote on the Microsoft Connect support issue vstest.executionengine.x86.exe (32 bit) - Not Closing (affects both x86 and x64 despite the title). 如果你对这个“改进”也有问题,那么请对Microsoft Connect支持问题vstest.executionengine.x86.exe(32位)进行投票- 不关闭 (尽管标题是影响x86和x64)。

I know this question is old, but I had this problem and some of the answers here sparked an idea. 我知道这个问题很老,但我遇到了这个问题,这里的一些答案引发了一个想法。 One of the first problems I encountered when trying to build unit/integration tests around SQLite was that MSTest (which we use for scripted builds) wasn't deploying all of the necessary dependencies to the test run's "Out" directory before running the test, so the tests failed. 在尝试围绕SQLite构建单元/集成测试时遇到的第一个问题之一是MSTest(我们用于脚本构建)在运行测试之前没有将所有必要的依赖项部署到测试运行的“Out”目录,所以测试失败了。 The best way I found to solve this problem was to add these attributes to my test class: 我发现解决此问题的最佳方法是将这些属性添加到我的测试类:

[TestClass]
**[DeploymentItem("System.Data.SQLite.dll")]
[DeploymentItem("x86\\SQLite.Interop.Dll")]**
public class TestClass

This appears to also solve this issue...I'm guessing this causes VSTest to load a different copy of these dependencies so that VSBuild can still do what it will with the copy in your normal /bin/ directory. 这似乎也解决了这个问题...我猜这会导致VSTest加载这些依赖项的不同副本,以便VSBuild仍然可以执行它在普通/ bin /目录中的副本。

Also make sure that your Database is installed to the correct folder 还要确保将数据库安装到正确的文件夹中
SQLite Connection Strings SQLite连接字符串

Data adapter that you may want to try as well using SQL Lite Using SQLitew with .NET 您可能希望使用SQL Lite 使用SQLitew与.NET一起尝试的数据适配器

SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.FailIfMissing = true;
builder.DataSource = "Insert the fully qualified path to your sqlite db";
SQLiteConnection connection = new SQLiteConnection(builder.ConnectionString);
try
{
  connection.Open();
}
catch(SqlException exp)
{
    // Log what you need from here.
    throw new InvalidOperationException("Whatever exception you want to throw", exp);
}

Read this Article to see if it helps to correct your issue as well System.Data.SQLite.View Ticket 阅读本文,看看它是否有助于纠正您的问题以及System.Data.SQLite.View Ticket

Try disposing of the connection as below. 尝试处理如下连接。 It worked fine for me. 它对我来说很好。

    private void Dispose(bool disposing)
    {
        if (_disposed) return;

        if (disposing)
        {
            if (_dbConnection != null)
            {
                _dbConnection.Cancel();
                _dbConnection.Close();
                _dbConnection.Dispose();
            }
        }

        _disposed = true;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM