Skip to content

Commit

Permalink
Core - LoadUrlAsync require url and remove SyncContext param
Browse files Browse the repository at this point in the history
- Remove url optional null, a Url is now required and an exception will be
  thrown if null or empty. If the browser wasn't loading an null was passed
  in then the task would have never resolved. This provides a predictable behaviour.
  A new WaitForInitialLoadAsync method was added to simplify waiting for initial
  browser load.
- Remove SynchronizationContext param, best to let the framework handle

Issue #3842
  • Loading branch information
amaitland committed Oct 28, 2021
1 parent 4a07af2 commit 4112340
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 47 deletions.
2 changes: 1 addition & 1 deletion CefSharp.OffScreen.Example/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private static async Task MainAsync(string url, string cachePath, double zoomLev
}
};
}
await browser.LoadUrlAsync();
await browser.WaitForInitialLoadAsync();

//Check preferences on the CEF UI Thread
await Cef.UIThreadTaskFactory.StartNew(delegate
Expand Down
2 changes: 1 addition & 1 deletion CefSharp.Test/ChromiumWebBrowserOffScreenFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Task IAsyncLifetime.InitializeAsync()
{
Browser = new ChromiumWebBrowser(CefExample.HelloWorldUrl);

return Browser.LoadUrlAsync();
return Browser.WaitForInitialLoadAsync();
}
}
}
3 changes: 1 addition & 2 deletions CefSharp/IWebBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,11 @@ public interface IWebBrowser : IDisposable
/// Load the <paramref name="url"/> in the main frame of the browser
/// </summary>
/// <param name="url">url to load</param>
/// <param name="ctx">SynchronizationContext to execute the continuation on, if null then the ThreadPool will be used.</param>
/// <returns>
/// A <see cref="Task{LoadUrlAsyncResponse}"/> that can be awaited to load the <paramref name="url"/> and return the HttpStatusCode and <see cref="CefErrorCode"/>.
/// A HttpStatusCode equal to 200 and <see cref="CefErrorCode.None"/> is considered a success.
/// </returns>
Task<LoadUrlAsyncResponse> LoadUrlAsync(string url = null, SynchronizationContext ctx = null);
Task<LoadUrlAsyncResponse> LoadUrlAsync(string url);

/// <summary>
/// Wait for the Browser to finish loading the initial web page.
Expand Down
4 changes: 2 additions & 2 deletions CefSharp/Internals/Partial/ChromiumWebBrowser.Partial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,10 @@ public void LoadUrl(string url)
}

/// <inheritdoc/>
public Task<LoadUrlAsyncResponse> LoadUrlAsync(string url = null, SynchronizationContext ctx = null)
public Task<LoadUrlAsyncResponse> LoadUrlAsync(string url)
{
//LoadUrlAsync is actually a static method so that CefSharp.Wpf.HwndHost can reuse the code
return CefSharp.WebBrowserExtensions.LoadUrlAsync(this, url, ctx);
return CefSharp.WebBrowserExtensions.LoadUrlAsync(this, url);
}

/// <inheritdoc/>
Expand Down
60 changes: 19 additions & 41 deletions CefSharp/WebBrowserExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,29 +247,30 @@ public static void StartDownload(this IWebBrowser browser, string url)
}

/// <summary>
/// See <see cref="IWebBrowser.LoadUrlAsync(string, SynchronizationContext)"/> for details
/// See <see cref="IWebBrowser.LoadUrlAsync(string)"/> for details
/// </summary>
/// <param name="chromiumWebBrowser">ChromiumWebBrowser instance (cannot be null)</param>
/// <summary>
/// Load the <paramref name="url"/> in the main frame of the browser
/// </summary>
/// <param name="url">url to load</param>
/// <param name="ctx">SynchronizationContext to execute the continuation on, if null then the ThreadPool will be used.</param>
/// <returns>See <see cref="IWebBrowser.LoadUrlAsync(string, SynchronizationContext)"/> for details</returns>
public static Task<LoadUrlAsyncResponse> LoadUrlAsync(IWebBrowser chromiumWebBrowser, string url = null, SynchronizationContext ctx = null)
/// <returns>See <see cref="IWebBrowser.LoadUrlAsync(string)"/> for details</returns>
public static Task<LoadUrlAsyncResponse> LoadUrlAsync(IWebBrowser chromiumWebBrowser, string url)
{
if(string.IsNullOrEmpty(url))
{
throw new ArgumentNullException(nameof(url));
}

var tcs = new TaskCompletionSource<LoadUrlAsyncResponse>();

EventHandler<LoadErrorEventArgs> loadErrorHandler = null;
EventHandler<LoadingStateChangedEventArgs> loadingStateChangeHandler = null;

loadErrorHandler = (sender, args) =>
{
//Ignore Aborted
//Currently invalid SSL certificates which aren't explicitly allowed
//end up with CefErrorCode.Aborted, I've created the following PR
//in the hopes of getting this fixed.
//https://bitbucket.org/chromiumembedded/cef/pull-requests/373
//Actions that trigger a download will raise an aborted error.
//Generally speaking Aborted is safe to ignore
if (args.ErrorCode == CefErrorCode.Aborted)
{
return;
Expand All @@ -281,20 +282,10 @@ public static Task<LoadUrlAsyncResponse> LoadUrlAsync(IWebBrowser chromiumWebBro
chromiumWebBrowser.LoadError -= loadErrorHandler;
chromiumWebBrowser.LoadingStateChanged -= loadingStateChangeHandler;

if (ctx == null)
{
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(args.ErrorCode, -1));
}
else
{
ctx.Post(new SendOrPostCallback((o) =>
{
tcs.TrySetResult(new LoadUrlAsyncResponse(args.ErrorCode, -1));
}), null);
}
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(args.ErrorCode, -1));
};

loadingStateChangeHandler = (sender, args) =>
Expand Down Expand Up @@ -322,30 +313,17 @@ public static Task<LoadUrlAsyncResponse> LoadUrlAsync(IWebBrowser chromiumWebBro
statusCode = -1;
}

if (ctx == null)
{
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(CefErrorCode.None, statusCode));
}
else
{
ctx.Post(new SendOrPostCallback((o) =>
{
tcs.TrySetResult(new LoadUrlAsyncResponse(CefErrorCode.None, statusCode));
}), null);
}
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(CefErrorCode.None, statusCode));
}
};

chromiumWebBrowser.LoadError += loadErrorHandler;
chromiumWebBrowser.LoadingStateChanged += loadingStateChangeHandler;

if (!string.IsNullOrEmpty(url))
{
chromiumWebBrowser.Load(url);
}
chromiumWebBrowser.Load(url);

return tcs.Task;
}
Expand Down

0 comments on commit 4112340

Please sign in to comment.