Bug 26706 - Cursor not closed on dispose
Summary: Cursor not closed on dispose
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.20.0
Hardware: PC Windows
: Normal enhancement
Target Milestone: ---
Assignee: dean.ellis
Depends on:
Reported: 2015-02-03 17:55 UTC by Adam Kapos
Modified: 2017-10-13 17:51 UTC (History)
4 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Adam Kapos 2015-02-03 17:55:33 UTC
If I create a cursor like this:

using (var musicCursor = Context.ContentResolver.Query(MediaStore.Audio.Media.ExternalContentUri, null, null, null, null))
    // Do something

Then repeat it a couple if times, I get errors like this on logcat:

02-02 23:05:39.770: E/CursorLeakDetecter(28387): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-02 23:05:39.770: E/CursorLeakDetecter(28387): at android.content.ContentResolver.query(ContentResolver.java:399)
02-02 23:05:39.770: E/CursorLeakDetecter(28387): at android.content.ContentResolver.query(ContentResolver.java:316)
02-02 23:05:39.770: E/CursorLeakDetecter(28387): at dalvik.system.NativeStart.run(Native Method)

Adding musicCursor.Close(); to the end of the using makes these errors go away.

The cursor should be automatically closed on Dispose. Please fix it.
Comment 1 Adam Kapos 2015-02-03 17:56:11 UTC
Xamarin (74260cb)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android (49a04b966feb40dfdba49d57ba16249b66d606a6)
Visual Studio plugin to enable development for Xamarin.Android.
Comment 2 Atsushi Eno 2015-02-04 00:14:11 UTC
jonp: did we claim that .NET IDisposable() automatically calls Java close() on public document? I don't think it's automatically possible to detect such ones when generating binding code.
Comment 3 Jonathan Pryor 2015-02-04 09:08:53 UTC
I certainly don't claiming that IDisposable.Dispose() automatically calls close().

It could be done -- check to see if the type implements java.lang.AutoCloseable, and if it does have Dispose(bool) call Close() -- but it hasn't been done yet.
Comment 4 Adam Kapos 2015-02-04 12:29:42 UTC
What does dispose do if it doesn't call close?
Comment 5 Atsushi Eno 2015-02-05 11:01:54 UTC
Dispose() disposes internal Java object handle.

Even if the corresponding Java API implemented AutoCloseable, we shouldn't change the semantics of Dispose() in prior to any API breaking version. It will cause existing user code calling Java close() method twice.
Comment 6 Emil Müller 2016-03-21 00:40:55 UTC
I believe the documentation needs some updating/clarification.

Is the correct way to properly utilize a cursor this way?

var cursor = some cursor;

try {

  // ...

finally {


Beacuse the documentation on Cursor says that you have to Dispose() it: https://developer.xamarin.com/api/member/System.Windows.Forms.Cursor.Dispose()/.
And here is some documentation that says you have to Close() it: https://developer.xamarin.com/guides/android/platform_features/intro_to_content_providers/part_2_-_using_the_contacts_contentprovier/.
Comment 7 Jon Douglas [MSFT] 2017-07-13 22:28:50 UTC
If possible, can we please get a reproduction project that demonstrates this behavior? This will help us confirm this issue and ultimately issue a fix if we determine this to be an issue with the ICursor implementation.

Seeing that ICursor is the following:

public interface ICursor : ICloseable, IJavaObject, IDisposable

It seems that one would have to call the respective .Close() prior to .Dispose().

Thus marking NEEDINFO as I tried to reproduce this in a quick sample app, and it seems to be working. However I believe a proper reproduction might be able to shed more light to this issue.
Comment 8 Jon Douglas [MSFT] 2017-10-13 17:51:10 UTC
Because we have not received a reply to our request for more information we are closing this issue. If you are still encountering this issue, please reopen the ticket with the requested information. Thanks!