-
Type: Task
-
Resolution: Works as Designed
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.5
-
Component/s: Read Operations
-
Environment:Windows
I cannot find a proper way to cancel a change stream watcher.
In the following example I can stop watching when I dispose the enumerator, but the exception is not correct in my opinion.
Instead of disposing the enumerator, I would like to run something like cursor.Cancel() to stop watching for changes and close the change stream. And It could throw an OperationCanceledException.
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
var cts = new CancellationTokenSource(5000); var client = new MongoClient("mongodb://localhost"); var db = client.GetDatabase("test"); var collection = db.GetCollection<BsonDocument>("test"); Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Start watching..."); var cursor = collection.Watch(); var enumerator = cursor.ToEnumerable().GetEnumerator(); cts.Token.Register(() => { Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Cancellation token was cancelled."); enumerator.Dispose(); }); try { while (enumerator.MoveNext()) { Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Received a change from database."); } } catch (Exception e) { Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Exception: {e.Message}"); } Console.WriteLine("Done");
Console output:
Console output: 10:50:55 - Start watching... 10:50:59 - Cancellation token was cancelled. 10:50:59 - Exception: Cannot access a disposed object. Object name: 'MongoDB.Driver.Core.Bindings.CoreSessionHandle'.
In the following example I get the correct exception, but the MoveNext method returns true every second and I have to check if the cursor has any document.
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
var cts = new CancellationTokenSource(5000); var client = new MongoClient("mongodb://localhost"); var db = client.GetDatabase("test"); var collection = db.GetCollection<BsonDocument>("test"); Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Start watching..."); var cursor = collection.Watch(); try { while (cursor.MoveNext(cts.Token)) { if(cursor.Current.Count()>0) Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Received {cursor.Current.Count()} changes from database."); else Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Nothing changed in database."); } } catch (Exception e) { Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Exception: {e.Message}"); } Console.WriteLine("Done");
Console output:
11:15:26 - Start watching... 11:15:26 - Nothing changed in database. 11:15:27 - Nothing changed in database. 11:15:28 - Nothing changed in database. 11:15:29 - Nothing changed in database. 11:15:30 - Exception: The operation was canceled. Done
Here is an example how to cancel a file download using the .net WebClient. The same pattern could fit the cancellation of a change stream watcher.
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
var cts = new CancellationTokenSource(5000); var wc = new WebClient(); IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy; defaultWebProxy.Credentials = CredentialCache.DefaultCredentials; wc.Proxy = defaultWebProxy; cts.Token.Register(() => { Console.WriteLine("Cancel!"); wc.CancelAsync(); }); Console.WriteLine("Downloading..."); try { wc.DownloadFile(new Uri("http://downloads.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-4.0.2.zip"), @"c:\temp\mongodb.zip"); } catch (Exception e) { Console.WriteLine("Downloading was cancelled"); }