Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] LiteDB 5 System.IO.IOException: The process cannot access the file because it is being used by another process #1656

Closed
DanTwomey opened this issue Apr 27, 2020 · 8 comments
Labels

Comments

@DanTwomey
Copy link

We currently have a client application which consists of a Windows Service and a WPF application, both utilising LiteDB and targeting .Net Framework 4.8.

The windows service runs under the local system account and the WPF app runs under the user's account.

We made the choice to upgrade from 4.1.4 to 5.0.7 in the hopes that concurrency was better supported.

Both WPF app and win service access the same LiteDB (read and write) with connection=shared using the below connection string:

"Filename=C:\temp\Test-v5.db;password=pass1234;connection=shared"

using (var db = new LiteDatabase(@"Filename=C:\temp\Test-v5.db;password=pass1234;connection=shared"))
{
	...
}

We seem to have come across a breaking issue however and can't seem to find anyone else having the same/similar issue or anything else that could fix it.

The service frequently polls the database to handle and process data that has been inserted by the WPF app with both read and write operations.
The WPF app also reads and writes to the database but on a more sporadic time frame based on user interaction.

Despite both applications accessing the database in the same way and both specifying connection=shared, we are getting exceptions from both as they appear to be clashing.

"System.IO.IOException: The process cannot access the file 'C:\temp\Test-v5.db' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at LiteDB.Engine.FileStreamFactory.GetStream(Boolean canWrite, Boolean sequencial)
   at LiteDB.Engine.StreamPool.<>c__DisplayClass3_0.<.ctor>b__0()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at LiteDB.Engine.DiskService..ctor(EngineSettings settings, Int32[] memorySegmentSizes)
   at LiteDB.Engine.LiteEngine..ctor(EngineSettings settings)
   at LiteDB.SharedEngine.OpenDatabase()
   at LiteDB.SharedEngine.Query(String collection, Query query)
   at LiteDB.LiteQueryable`1.<ToDocuments>d__26.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Pixel_Upload_Service.UploadService.GetPendingJobsFromLiteDB(Boolean _allJobs) in D:\Users\Daniel\Desktop\LiteDB v5 Test\Upload Service\UploadService.cs:line 2654"

As a side note when testing this issue and trying to figure out what was going on, we found that we did not get any exceptions with two WPF apps reading and writing from the same database, however as soon as we swap one WPF app out for a Windows Service, we start getting exceptions.

Does anyone know how we can stop this happening?

@lbnascimento
Copy link
Collaborator

@DanTwomey Could you try with the latest master?

@DanTwomey
Copy link
Author

@lbnascimento This seems to have worked, don't seem to be getting the exceptions any more but will keep an eye out.

Do you have an ETA on a NuGet release?
If not I assume this is stable enough to go into production?

@lbnascimento
Copy link
Collaborator

@DanTwomey Next incremental release should be out soon, no ETA though. However, if you check the commits since the latest release, most of them are fixes for specific issues in the mapper. No internal changes to the engine were made (other than the fix for this issue, which was very simple).

@DanTwomey
Copy link
Author

@lbnascimento

I seem to still be getting System IO Exceptions with the latest Master, If the WIndows Service is running and accessing the database first and then the WPF app launches and attempts to use the database I get a System IO Exception.

If I launch the WPF app first, then start the service, I don't get any exceptions and I can continue to close and re-launch the WPF app with no issues.

I had both of these exceptions from the WPF App whilst the service was started first:

"System.IO.IOException: The process cannot access the file 'C:\temp\Test-v5.db' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at LiteDB.Engine.FileStreamFactory.GetStream(Boolean canWrite, Boolean sequencial) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Engine\Disk\StreamFactory\FileStreamFactory.cs:line 43
   at LiteDB.Engine.StreamPool.<>c__DisplayClass3_0.<.ctor>b__0() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Engine\Disk\StreamFactory\StreamPool.cs:line 29
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at LiteDB.Engine.StreamPool.get_Writer() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Engine\Disk\StreamFactory\StreamPool.cs:line 35
   at LiteDB.Engine.DiskService..ctor(EngineSettings settings, Int32[] memorySegmentSizes) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Engine\Disk\DiskService.cs:line 59
   at LiteDB.Engine.LiteEngine..ctor(EngineSettings settings) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Engine\LiteEngine.cs:line 115
   at LiteDB.SharedEngine.OpenDatabase() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Shared\SharedEngine.cs:line 55
   at LiteDB.SharedEngine.Query(String collection, Query query) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Shared\SharedEngine.cs:line 138
   at LiteDB.LiteQueryable`1.ExecuteReader() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteQueryable.cs:line 238
   at LiteDB.LiteQueryable`1.<ToDocuments>d__26.MoveNext() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteQueryable.cs:line 246
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at LiteDB.LiteCollection`1.FindOne(BsonExpression predicate) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\Collections\Find.cs:line 73
   at LiteDB.LiteCollection`1.FindOne(Expression`1 predicate) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\Collections\Find.cs:line 88
   at Helpers.JobHelper.GetJobFromLiteDB(String _jobId) in D:\Users\Daniel\Desktop\LiteDB v5 Test\Helpers\JobHelper.cs:line 79"

Mutex exception I wasn't getting yesterday:

"System.UnauthorizedAccessException: Access to the path 'Global\C26B5942FD8ABA8D203C8DC30C8BE263EFB29177.Mutex' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(Boolean initiallyOwned, String name, Boolean& createdNew, SECURITY_ATTRIBUTES secAttrs)
   at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity)
   at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name)
   at LiteDB.SharedEngine..ctor(EngineSettings settings) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Shared\SharedEngine.cs:line 26
   at LiteDB.ConnectionString.CreateEngine() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Structures\ConnectionString.cs:line 116
   at LiteDB.LiteDatabase..ctor(ConnectionString connectionString, BsonMapper mapper) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteDatabase.cs:line 53
   at LiteDB.LiteDatabase..ctor(String connectionString, BsonMapper mapper) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteDatabase.cs:line 36
   at Helpers.LiteDBHelper.GetDeviceFromLiteDB() in D:\Users\Daniel\Desktop\LiteDB v5 Test\Helpers\LiteDBHelper.cs:line 109"

@DanTwomey
Copy link
Author

Some more info that could be useful:

If I run the WPF App as Administrator (Right click -> Run As Administrator) there are no exceptions from the WPF App, without elevation, I get the exceptions straight away.

@lbnascimento
Copy link
Collaborator

@DanTwomey Could you test with the latest master? I made some changes, I believe it is working now.

@DanTwomey
Copy link
Author

@lbnascimento

The changes seem to have fixed the issue with the Mutex being used by both applications, both are now able to read and write to the database, however we are now randomly getting this exception:

"System.Threading.AbandonedMutexException: The wait completed due to an abandoned mutex.
   at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
   at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
   at System.Threading.WaitHandle.WaitOne()
   at LiteDB.SharedEngine.OpenDatabase() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Shared\SharedEngine.cs:line 64
   at LiteDB.SharedEngine.Query(String collection, Query query) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Shared\SharedEngine.cs:line 157
   at LiteDB.LiteQueryable`1.ExecuteReader() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteQueryable.cs:line 238
   at LiteDB.LiteQueryable`1.<ToDocuments>d__26.MoveNext() in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\LiteQueryable.cs:line 246
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at LiteDB.LiteCollection`1.FindOne(BsonExpression predicate) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\Collections\Find.cs:line 73
   at LiteDB.LiteCollection`1.FindOne(Expression`1 predicate) in D:\Users\Daniel\Downloads\LiteDB-master\LiteDB-master\LiteDB\Client\Database\Collections\Find.cs:line 88
   at Pixel_Upload_Service.Helpers.JobHelper.GetJobFromLiteDB(String _jobId) in H:\Repos\Upload Service\Helpers\JobHelper.cs:line 29"

Once this exception happens in the service, the WPF app will infinitely wait on the first collection.FindOne() and never continue until the service has been restarted.

Unfortunately we cannot yet find a way to force this issue to reproduce consistently to give any steps.

@lbnascimento
Copy link
Collaborator

@DanTwomey I made a commit that should fix the AbandonedMutexException problem, try it and see if it works for you. I'm going to close this issue, since the original issue was solved. If the problem persists if you have another problem, please open another issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants