Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2372

Unwatch/stop a change stream

    • Type: Icon: Task Task
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 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");
      }
      

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            daniel.moqvist@knowit.se daniel moqvist
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: