Skip to content

Commit 7177342

Browse files
committed
Wpf/WinForms/OffScreen - Standardize InternalIsBrowserInitialized
- Add InternalIsBrowserInitialized to partial class - Move ThrowExceptionIfDisposed/ThrowExceptionIfBrowserNotInitialized to partial class - Remove checks from DevToolsExtensions.ExecuteDevToolsMethodAsync as the checks were already in GetBrowser In WPF it's no longer necessary to have a custom implementation, will leave the Dependency property (won't action #3033 at this point in time)
1 parent 124490e commit 7177342

File tree

6 files changed

+73
-82
lines changed

6 files changed

+73
-82
lines changed

CefSharp.OffScreen/ChromiumWebBrowser.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ public bool IsDisposed
6767
/// A flag that indicates whether the WebBrowser is initialized (true) or not (false).
6868
/// </summary>
6969
/// <value><c>true</c> if this instance is browser initialized; otherwise, <c>false</c>.</value>
70-
public bool IsBrowserInitialized { get; private set; }
70+
public bool IsBrowserInitialized
71+
{
72+
get { return InternalIsBrowserInitialized(); }
73+
}
7174
/// <summary>
7275
/// A flag that indicates whether the control is currently loading one or more web pages (true) or not (false).
7376
/// </summary>
@@ -240,7 +243,7 @@ protected virtual void Dispose(bool disposing)
240243
if (disposing)
241244
{
242245
CanExecuteJavascriptInMainFrame = false;
243-
IsBrowserInitialized = false;
246+
Interlocked.Exchange(ref browserInitialized, 0);
244247

245248
// Don't reference event listeners any longer:
246249
AddressChanged = null;
@@ -476,8 +479,8 @@ bool IWebBrowser.Focus()
476479
/// <returns>browser instance or null</returns>
477480
public IBrowser GetBrowser()
478481
{
479-
this.ThrowExceptionIfDisposed();
480-
this.ThrowExceptionIfBrowserNotInitialized();
482+
ThrowExceptionIfDisposed();
483+
ThrowExceptionIfBrowserNotInitialized();
481484

482485
return browser;
483486
}
@@ -662,7 +665,7 @@ void IWebBrowserInternal.OnAfterBrowserCreated(IBrowser browser)
662665
{
663666
this.browser = browser;
664667

665-
IsBrowserInitialized = true;
668+
Interlocked.Exchange(ref browserInitialized, 1);
666669

667670
BrowserInitialized?.Invoke(this, EventArgs.Empty);
668671
}

CefSharp.WinForms/ChromiumWebBrowser.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@ public IRequestContext RequestContext
239239
/// </summary>
240240
/// <value><c>true</c> if this instance is browser initialized; otherwise, <c>false</c>.</value>
241241
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), DefaultValue(false)]
242-
public bool IsBrowserInitialized { get; private set; }
242+
public bool IsBrowserInitialized
243+
{
244+
get { return InternalIsBrowserInitialized(); }
245+
}
243246

244247
/// <summary>
245248
/// ParentFormMessageInterceptor hooks the Form handle and forwards
@@ -399,8 +402,8 @@ private void InternalDispose(bool disposing)
399402
{
400403
if (disposing)
401404
{
405+
Interlocked.Exchange(ref browserInitialized, 0);
402406
CanExecuteJavascriptInMainFrame = false;
403-
IsBrowserInitialized = false;
404407

405408
// Don't maintain a reference to event listeners anylonger:
406409
AddressChanged = null;
@@ -605,7 +608,7 @@ private void CreateBrowser()
605608
void IWebBrowserInternal.OnAfterBrowserCreated(IBrowser browser)
606609
{
607610
this.browser = browser;
608-
IsBrowserInitialized = true;
611+
Interlocked.Exchange(ref browserInitialized, 1);
609612

610613
// By the time this callback gets called, this control
611614
// is most likely hooked into a browser Form of some sort.
@@ -782,8 +785,8 @@ protected override void OnGotFocus(EventArgs e)
782785
/// <returns>browser instance or null</returns>
783786
public IBrowser GetBrowser()
784787
{
785-
this.ThrowExceptionIfDisposed();
786-
this.ThrowExceptionIfBrowserNotInitialized();
788+
ThrowExceptionIfDisposed();
789+
ThrowExceptionIfBrowserNotInitialized();
787790

788791
return browser;
789792
}

CefSharp.Wpf/ChromiumWebBrowser.cs

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ public partial class ChromiumWebBrowser : Control, IRenderWebBrowser, IWpfWebBro
9696
/// </summary>
9797
private bool browserCreated;
9898
/// <summary>
99-
/// The browser initialized - boolean represented as 0 (false) and 1(true) as we use Interlocker to increment/reset
100-
/// </summary>
101-
private int browserInitialized;
102-
/// <summary>
10399
/// The image that represents this browser instances
104100
/// </summary>
105101
private Image image;
@@ -1212,16 +1208,6 @@ public bool IsLoading
12121208
#endregion IsLoading dependency property
12131209

12141210
#region IsBrowserInitialized dependency property
1215-
1216-
/// <summary>
1217-
/// A flag that indicates whether the WebBrowser is initialized (true) or not (false).
1218-
/// </summary>
1219-
/// <value><c>true</c> if this instance is browser initialized; otherwise, <c>false</c>.</value>
1220-
bool IWebBrowser.IsBrowserInitialized
1221-
{
1222-
get { return InternalIsBrowserInitialized(); }
1223-
}
1224-
12251211
/// <summary>
12261212
/// A flag that indicates whether the WebBrowser is initialized (true) or not (false).
12271213
/// </summary>
@@ -2507,28 +2493,10 @@ public IJavascriptObjectRepository JavascriptObjectRepository
25072493
/// <returns>browser instance or null</returns>
25082494
public IBrowser GetBrowser()
25092495
{
2510-
this.ThrowExceptionIfDisposed();
2511-
2512-
//We don't use the this.ThrowExceptionIfBrowserNotInitialized(); extension method here
2513-
// As it relies on the IWebBrowser.IsBrowserInitialized property which is a DependencyProperty
2514-
// in WPF and will throw an InvalidOperationException if called on a Non-UI thread.
2515-
if (!InternalIsBrowserInitialized())
2516-
{
2517-
throw new Exception(WebBrowserExtensions.BrowserNotInitializedExceptionErrorMessage);
2518-
}
2496+
ThrowExceptionIfDisposed();
2497+
ThrowExceptionIfBrowserNotInitialized();
25192498

25202499
return browser;
25212500
}
2522-
2523-
/// <summary>
2524-
/// Check is browserisinitialized
2525-
/// </summary>
2526-
/// <returns>true if browser is initialized</returns>
2527-
private bool InternalIsBrowserInitialized()
2528-
{
2529-
// Use CompareExchange to read the current value - if disposeCount is 1, we set it to 1, effectively a no-op
2530-
// Volatile.Read would likely use a memory barrier which I believe is unnecessary in this scenario
2531-
return Interlocked.CompareExchange(ref browserInitialized, 0, 0) == 1;
2532-
}
25332501
}
25342502
}

CefSharp/DevToolsExtensions.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ public static Task<int> ExecuteDevToolsMethodAsync(this IBrowser browser, int me
9696
/// unsuccessfully submitted for validation, this value will be 0.</returns>
9797
public static Task<int> ExecuteDevToolsMethodAsync(this IWebBrowser chromiumWebBrowser, int messageId, string method, IDictionary<string, object> parameters = null)
9898
{
99-
((IWebBrowserInternal)chromiumWebBrowser).ThrowExceptionIfDisposed();
100-
((IWebBrowserInternal)chromiumWebBrowser).ThrowExceptionIfBrowserNotInitialized();
101-
10299
var browser = chromiumWebBrowser.GetBrowser();
103100

104101
return browser.ExecuteDevToolsMethodAsync(messageId, method, parameters);

CefSharp/Internals/Partial/ChromiumWebBrowser.Partial.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.ComponentModel;
7+
using System.Threading;
78
using CefSharp.Internals;
89

910
#if OFFSCREEN
@@ -18,11 +19,21 @@ namespace CefSharp.WinForms
1819
//WPF, Winforms and Offscreen
1920
public partial class ChromiumWebBrowser
2021
{
22+
public const string BrowserNotInitializedExceptionErrorMessage =
23+
"The ChromiumWebBrowser instance creates the underlying Chromium Embedded Framework (CEF) browser instance in an async fashion. " +
24+
"The undelying CefBrowser instance is not yet initialized. Use the IsBrowserInitializedChanged event and check " +
25+
"the IsBrowserInitialized property to determine when the browser has been initialized.";
26+
2127
/// <summary>
2228
/// Used as workaround for issue https://github.com/cefsharp/CefSharp/issues/3021
2329
/// </summary>
2430
private long canExecuteJavascriptInMainFrameId;
2531

32+
/// <summary>
33+
/// The browser initialized - boolean represented as 0 (false) and 1(true) as we use Interlocker to increment/reset
34+
/// </summary>
35+
private int browserInitialized;
36+
2637
/// <summary>
2738
/// A flag that indicates if you can execute javascript in the main frame.
2839
/// Flag is set to true in IRenderProcessMessageHandler.OnContextCreated.
@@ -184,6 +195,15 @@ public partial class ChromiumWebBrowser
184195
/// </summary>
185196
public event EventHandler<JavascriptMessageReceivedEventArgs> JavascriptMessageReceived;
186197

198+
/// <summary>
199+
/// A flag that indicates whether the WebBrowser is initialized (true) or not (false).
200+
/// </summary>
201+
/// <value><c>true</c> if this instance is browser initialized; otherwise, <c>false</c>.</value>
202+
bool IWebBrowser.IsBrowserInitialized
203+
{
204+
get { return InternalIsBrowserInitialized(); }
205+
}
206+
187207
void IWebBrowserInternal.SetCanExecuteJavascriptOnMainFrame(long frameId, bool canExecute)
188208
{
189209
//When loading pages of a different origin the frameId changes
@@ -284,5 +304,40 @@ private void SetHandlersToNullExceptLifeSpan()
284304
ResourceRequestHandlerFactory = null;
285305
RenderProcessMessageHandler = null;
286306
}
307+
308+
/// <summary>
309+
/// Check is browser is initialized
310+
/// </summary>
311+
/// <returns>true if browser is initialized</returns>
312+
private bool InternalIsBrowserInitialized()
313+
{
314+
// Use CompareExchange to read the current value - if disposeCount is 1, we set it to 1, effectively a no-op
315+
// Volatile.Read would likely use a memory barrier which I believe is unnecessary in this scenario
316+
return Interlocked.CompareExchange(ref browserInitialized, 0, 0) == 1;
317+
}
318+
319+
/// <summary>
320+
/// Throw exception if browser not initialized.
321+
/// </summary>
322+
/// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
323+
private void ThrowExceptionIfBrowserNotInitialized()
324+
{
325+
if (!InternalIsBrowserInitialized())
326+
{
327+
throw new Exception(BrowserNotInitializedExceptionErrorMessage);
328+
}
329+
}
330+
331+
/// <summary>
332+
/// Throw exception if disposed.
333+
/// </summary>
334+
/// <exception cref="ObjectDisposedException">Thrown when a supplied object has been disposed.</exception>
335+
private void ThrowExceptionIfDisposed()
336+
{
337+
if (IsDisposed)
338+
{
339+
throw new ObjectDisposedException("browser", "Browser has been disposed");
340+
}
341+
}
287342
}
288343
}

CefSharp/WebBrowserExtensions.cs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ namespace CefSharp
1818
/// </summary>
1919
public static class WebBrowserExtensions
2020
{
21-
public const string BrowserNotInitializedExceptionErrorMessage =
22-
"The ChromiumWebBrowser instance creates the underlying Chromium Embedded Framework (CEF) browser instance in an async fashion. " +
23-
"The undelying CefBrowser instance is not yet initialized. Use the IsBrowserInitializedChanged event and check " +
24-
"the IsBrowserInitialized property to determine when the browser has been initialized.";
25-
2621
#region Legacy Javascript Binding
2722
/// <summary>
2823
/// Registers a Javascript object in this specific browser instance.
@@ -1160,36 +1155,6 @@ public static string GetScriptForJavascriptMethodWithArgs(string methodName, obj
11601155
return stringBuilder.ToString();
11611156
}
11621157

1163-
/// <summary>
1164-
/// An IWebBrowser extension method that throw exception if browser not initialized.
1165-
/// </summary>
1166-
/// <remarks>
1167-
/// Not used in WPF as IsBrowserInitialized is a dependency property and can only be checked on the UI thread(throws
1168-
/// InvalidOperationException if called on another Thread).
1169-
/// </remarks>
1170-
/// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
1171-
/// <param name="browser">The ChromiumWebBrowser instance this method extends.</param>
1172-
public static void ThrowExceptionIfBrowserNotInitialized(this IWebBrowserInternal browser)
1173-
{
1174-
if (!browser.IsBrowserInitialized)
1175-
{
1176-
throw new Exception(BrowserNotInitializedExceptionErrorMessage);
1177-
}
1178-
}
1179-
1180-
/// <summary>
1181-
/// An IWebBrowser extension method that throw exception if disposed.
1182-
/// </summary>
1183-
/// <exception cref="ObjectDisposedException">Thrown when a supplied object has been disposed.</exception>
1184-
/// <param name="browser">The ChromiumWebBrowser instance this method extends.</param>
1185-
public static void ThrowExceptionIfDisposed(this IWebBrowserInternal browser)
1186-
{
1187-
if (browser.IsDisposed)
1188-
{
1189-
throw new ObjectDisposedException("browser", "Browser has been disposed");
1190-
}
1191-
}
1192-
11931158
/// <summary>
11941159
/// Throw exception if frame null.
11951160
/// </summary>

0 commit comments

Comments
 (0)