How to correctly use VisitUrlCookies?

Having problems with building or using the CefGlue .NET/Mono binding? Ask your questions here.

Moderator: fddima

How to correctly use VisitUrlCookies?

Postby gwynjudd » Sun Feb 21, 2016 10:24 pm

Hello,

I'm having a hard time getting this to work reliably with CefGlue. I want to run VisitUrlCookies to get all cookies. Based on a suggestion in some other posts, it looks like the Visit method in my CefCookieVisitor will be called repeatedly, and once all of the cookies are found, the Dispose method will be called. What I find is that this seems to be unreliable. I'm finding that the Visit method is being called for the cookies (of which there is only one), but once that has happened, the Dispose method isn't always called. Some of the time it is called ok, but in other cases, it isn't called. Here is the code for my visitor:

namespace MyCookieVisitor
{
using System.Net;
using System.Threading.Tasks;
using Xilium.CefGlue;

internal class CookieVisitor : CefCookieVisitor
{
private TaskCompletionSource<CookieCollection> completionSource;

public CookieVisitor()
{
this.Cookies = new CookieCollection();
}

public CookieCollection Cookies { get; private set; }

protected override bool Visit(CefCookie cookie, int count, int total, out bool delete)
{
this.Cookies.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));

delete = false;
return true;
}

public void GetCookies(string address, TaskCompletionSource<CookieCollection> completionSource)
{
CefCookieManager.GetGlobal(null).VisitUrlCookies(address, false, this);
this.completionSource = completionSource;
}

protected override void Dispose(bool disposing)
{
this.completionSource.SetResult(this.Cookies);
}
}
}

Is there anything wrong with what I'm doing here?
gwynjudd
Newbie
 
Posts: 9
Joined: Mon Aug 03, 2015 5:22 pm

Re: How to correctly use VisitUrlCookies?

Postby amaitland » Sun Feb 21, 2016 10:36 pm

Evaluate total and count to determine when there are no more cookies.

Also you haven't taken into account when there are no cookies present the call will never be made, so I'd suggest some sort of timeout.
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1290
Joined: Wed Jan 14, 2015 2:35 am

Re: How to correctly use VisitUrlCookies?

Postby magreenblatt » Mon Feb 22, 2016 12:56 pm

amaitland wrote:Also you haven't taken into account when there are no cookies present the call will never be made, so I'd suggest some sort of timeout.

In C++ the CefCookieVisitor destructor will still be called even if there are no cookies. I'm not sure if C# exposes a similar concept.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: How to correctly use VisitUrlCookies?

Postby gwynjudd » Mon Feb 22, 2016 3:51 pm

magreenblatt wrote:In C++ the CefCookieVisitor destructor will still be called even if there are no cookies. I'm not sure if C# exposes a similar concept.


C# uses garbage collection - the Dispose method will eventually be called, but it is not guaranteed to be done in a timely fashion. Also relying on destructors (finalizers) is considered very bad practice in .Net programming. An explicit "done" event would be a lot more usable.

I came up with a different plan, but I don't know if it is right:

Code: Select all
namespace MyCookieVisitor
{
   using System;
   using System.Net;
   using System.Threading.Tasks;
   using Xilium.CefGlue;

   internal class CompletionCallback : CefCompletionCallback
   {
      public delegate void CompletionCallbackDelegate();
      private CompletionCallbackDelegate completionCallbackDelegate;

      public CompletionCallback(CompletionCallbackDelegate completionCallbackDelegate)
      {
         this.completionCallbackDelegate = completionCallbackDelegate;
      }

      protected override void OnComplete()
      {
         this.completionCallbackDelegate();
      }
   }

   internal class CookieVisitor : CefCookieVisitor
   {
      private TaskCompletionSource<CookieCollection> completionSource;

      public CookieVisitor()
      {
         this.Cookies = new CookieCollection();
      }

      private CookieCollection Cookies { get; set; }

      protected override bool Visit(CefCookie cookie, int count, int total, out bool delete)
      {
         this.Cookies.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));

         delete = false;
         return true;
      }

      public void GetCookies(string address, TaskCompletionSource<CookieCollection> completionSource)
      {
         CefCookieManager manager = null;
         manager = CefCookieManager.GetGlobal(new CompletionCallback(() =>
         {
            if (manager != null)
            {
               manager.VisitUrlCookies(address, false, this);
               completionSource.SetResult(this.Cookies);
            }
         }));
      }
   }
}


The idea is that in the completion callback for the GetGlobal call (which runs in the IO thread), call VisitUrlCookies and then set the result in a synchronous way. It seems to work in my use case, but I don't know if VisitUrlCookies is actually synchronous in the IO thread.

amaitland wrote:Evaluate total and count to determine when there are no more cookies.

Also you haven't taken into account when there are no cookies present the call will never be made, so I'd suggest some sort of timeout.


This is the only other alternative that I've come up with, but it's quite distasteful so hopefully I don't have to rely on that.
gwynjudd
Newbie
 
Posts: 9
Joined: Mon Aug 03, 2015 5:22 pm

Re: How to correctly use VisitUrlCookies?

Postby fddima » Wed Mar 23, 2016 6:17 am

Hello.

1. This method executed synchronously on IO thread. But there is looks like implementation detail.

2. Dispose method now will be called, so cookie visitor implementation can rely on Dispose method.
With one note, to previous post, that you should always call base.Dispose(disposing) otherwise you will get memory leak.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am


Return to CefGlue Forum

Who is online

Users browsing this forum: No registered users and 15 guests