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

Can't .DeleteRealm() Even After .Dispose() #1970

Closed
mathaou opened this issue Mar 17, 2020 · 5 comments
Closed

Can't .DeleteRealm() Even After .Dispose() #1970

mathaou opened this issue Mar 17, 2020 · 5 comments
Labels

Comments

@mathaou
Copy link

@mathaou mathaou commented Mar 17, 2020

Goals

Trying to replace a .realm file used by a configuration offline.

Expected Results

After I .Dispose() the instance, I expect .DeleteRealm() to remove all files associated with it.

Actual Results

Error thrown. File in use by another process.

Steps to Reproduce

Create a Realm instance, attach a .RealmChanged handler, and get a reference to the .All.

Code Sample

Uri.TryCreate(realmPath, UriKind.Relative, out var outPathUri);
RealmConfigurationBase configuration = new FullSyncConfiguration(outPathUri, _currentUser, _realmFile)
{
    ObjectClasses = typesInSelectedRealm,
    SchemaVersion = 1
};

_realmInstance = Realm.GetInstance(configuration);

if(_realmInstance != null) _realmInstance.RealmChanged += LoadDataOnChange;

Trying to copy .realm file with same format from a USB Drive

if(_realmInstance != null) 
{
    _realmInstance.RealmChanged -= LoadDataOnChange; // figure it's good to clear all external references to Realm object
    _realmInstance.Dispose();
    GC.Collect();
    Thread.Sleep(1000); // both of these are me trying to just make darn sure that everything is cleaned up and has had enough time to do so
    Realm.DeleteRealm(_realmInstance.Config); // error
}

Error thrown: The process cannot access the file '...\test.realm' because it is being used by another process.

I've already seen this thread, which is the closest I've found to my issue and a possible solution, although it was for IOS so I'm not sure how much is applicable to my situation.

Version of Realm and Tooling

  • Realm Object Server Version: ? (you can see this as well in Studio once connected to a Realm instance) 4.2.0
  • Flavor:
    • Realm Cloud
    • Self-Hosted
  • Server OS & Version: ? (e.g. CentOS 6) Windows 10 Enterprise 1806
  • Client SDK Version: ? 4.2.0
  • Client OS & Version: ? Windows 10 Enterprise 1806
@realm-probot realm-probot bot added the O-Community label Mar 17, 2020
@mathaou

This comment has been minimized.

Copy link
Author

@mathaou mathaou commented Mar 17, 2020

@fealebenpae

This comment has been minimized.

Copy link
Contributor

@fealebenpae fealebenpae commented Mar 17, 2020

Hey @mathaou,

When you open a synchronized realm the framework spawns a worker thread which runs the sync session. By default after you close the last instance of a synchronized realm file its sync session lingers a bit more in the worker thread to make sure that changes are propagated.

It seems like you're opening a realm and then shortly thereafter disposing it and trying to delete it. What I think is happening is that the sync session is still performing synchronization in the background, because when you open a synchronized realm with Realm.GetInstance() you get a Realm instance right away but it doesn't hold any data until the sync session is completely done synchronizing.

My suggestion is to try using Realm.GetInstanceAsync() instead - the difference is that this method will wait for initial synchronization to be completed before returning the Realm instance, which means that after you dispose the realm instance the sync session should release the realm file right away as it doesn't actually have anything to keep synchronizing (Realm.GetInstanceAsync() already took care of the initial synchronization).

Alternatively, you can call realm.GetSession().Stop() before disposing your realm instance - this will stop the sync session which means it won't linger after you close the realm to finish synchronization and the file should be able to be deleted.

Out of curiosity, under what circumstances do you need to delete a synchronized realm file? If it's a file you'll be opening again that'll just mean it'll need to be downloaded from the server all over again as opposed to just resuming from where it left off.

@mathaou

This comment has been minimized.

Copy link
Author

@mathaou mathaou commented Mar 17, 2020

@fealebenpae You almost solved my issue! Not sure why, but I can successfully overwrite the file but only once...

await Realm.GetInstanceAsync(configuration) threw an Exception for me. Just said to look for InnerException for more info, but wasn't very helpful. It's a RealmException of some kind I'm pretty sure. So close! This was the secret sauce:

_realmInstance.GetSession().Stop();
_realmInstance.Dispose();

EDIT:
Here's the stacktrace for that error with GetInstanceAsync()

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Realms.Sync.SyncConfigurationBase.<CreateRealmAsync>d__37.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

Now I just need to find why I can only do overwrite once...

@mathaou

This comment has been minimized.

Copy link
Author

@mathaou mathaou commented Mar 17, 2020

@mathaou

This comment has been minimized.

Copy link
Author

@mathaou mathaou commented Mar 18, 2020

It works once and then I just restart the app. Good enough for my purposes.

@mathaou mathaou closed this Mar 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.