| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -237,15 +237,15 @@ Task<JavascriptResponse^>^ CefFrameWrapper::EvaluateScriptAsync(String^ script, | |||
| 237 | 237 | //If we're unable to get the underlying browser/browserhost then return null | |
| 238 | 238 | if (!browser.get() || !host.get()) | |
| 239 | 239 | { | |
| 240 | - return nullptr; | ||
| 240 | + return Task::FromException<JavascriptResponse^>(gcnew InvalidOperationException("Browser host not available")); | ||
| 241 | 241 | } | |
| 242 | 242 | ||
| 243 | 243 | auto client = static_cast<ClientAdapter*>(host->GetClient().get()); | |
| 244 | 244 | ||
| 245 | 245 | auto pendingTaskRepository = client->GetPendingTaskRepository(); | |
| 246 | 246 | ||
| 247 | 247 | //create a new taskcompletionsource | |
| 248 | - auto idAndComplectionSource = pendingTaskRepository->CreatePendingTask(timeout); | ||
| 248 | + auto idAndComplectionSource = pendingTaskRepository->CreatePendingTask(Identifier, timeout); | ||
| 249 | 249 | ||
| 250 | 250 | if (useImmediatelyInvokedFuncExpression) | |
| 251 | 251 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -701,6 +701,8 @@ namespace CefSharp | |||
| 701 | 701 | ||
| 702 | 702 | void ClientAdapter::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser, TerminationStatus status, int errorCode, const CefString& errorString) | |
| 703 | 703 | { | |
| 704 | + _pendingTaskRepository->CancelPendingTasks(); | ||
| 705 | + | ||
| 704 | 706 | auto handler = _browserControl->RequestHandler; | |
| 705 | 707 | ||
| 706 | 708 | if (handler != nullptr) | |
@@ -1382,9 +1384,13 @@ namespace CefSharp | |||
| 1382 | 1384 | //we get here, only continue if we have a valid frame reference | |
| 1383 | 1385 | if (frame.get() && frame->IsValid()) | |
| 1384 | 1386 | { | |
| 1387 | + auto frameId = StringUtils::ToClr(frame->GetIdentifier()); | ||
| 1388 | + | ||
| 1389 | + _pendingTaskRepository->CancelPendingTasks(frameId); | ||
| 1390 | + | ||
| 1385 | 1391 | if (frame->IsMain()) | |
| 1386 | 1392 | { | |
| 1387 | - _browserControl->SetCanExecuteJavascriptOnMainFrame(StringUtils::ToClr(frame->GetIdentifier()), false); | ||
| 1393 | + _browserControl->SetCanExecuteJavascriptOnMainFrame(frameId, false); | ||
| 1388 | 1394 | } | |
| 1389 | 1395 | ||
| 1390 | 1396 | auto handler = _browserControl->RenderProcessMessageHandler; | |
@@ -1475,14 +1481,16 @@ namespace CefSharp | |||
| 1475 | 1481 | return true; | |
| 1476 | 1482 | } | |
| 1477 | 1483 | ||
| 1484 | + auto frameId = StringUtils::ToClr(frame->GetIdentifier()); | ||
| 1485 | + | ||
| 1478 | 1486 | auto callbackFactory = browserAdapter->JavascriptCallbackFactory; | |
| 1479 | 1487 | ||
| 1480 | 1488 | auto success = argList->GetBool(0); | |
| 1481 | 1489 | auto callbackId = GetInt64(argList, 1); | |
| 1482 | 1490 | ||
| 1483 | 1491 | auto pendingTask = name == kEvaluateJavascriptResponse ? | |
| 1484 | - _pendingTaskRepository->RemovePendingTask(callbackId) : | ||
| 1485 | - _pendingTaskRepository->RemoveJavascriptCallbackPendingTask(callbackId); | ||
| 1492 | + _pendingTaskRepository->RemovePendingTask(frameId, callbackId) : | ||
| 1493 | + _pendingTaskRepository->RemoveJavascriptCallbackPendingTask(frameId, callbackId); | ||
| 1486 | 1494 | ||
| 1487 | 1495 | if (pendingTask != nullptr) | |
| 1488 | 1496 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,8 +70,7 @@ namespace CefSharp | |||
| 70 | 70 | ||
| 71 | 71 | CloseAllPopups(true); | |
| 72 | 72 | ||
| 73 | - //this will dispose the repository and cancel all pending tasks | ||
| 74 | - delete _pendingTaskRepository; | ||
| 73 | + _pendingTaskRepository->CancelPendingTasks(); | ||
| 75 | 74 | ||
| 76 | 75 | _browser = nullptr; | |
| 77 | 76 | _browserControl = nullptr; | |
@@ -80,6 +79,7 @@ namespace CefSharp | |||
| 80 | 79 | _tooltip = nullptr; | |
| 81 | 80 | _browserAdapter = nullptr; | |
| 82 | 81 | _popupBrowsers = nullptr; | |
| 82 | + _pendingTaskRepository = nullptr; | ||
| 83 | 83 | } | |
| 84 | 84 | ||
| 85 | 85 | HWND GetBrowserHwnd() { return _browserHwnd; } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,30 +27,31 @@ namespace CefSharp | |||
| 27 | 27 | auto browser = GetBrowser(); | |
| 28 | 28 | if (browser == nullptr) | |
| 29 | 29 | { | |
| 30 | - throw gcnew InvalidOperationException("Browser instance is null. Check CanExecute before calling this method."); | ||
| 30 | + return Task::FromException<JavascriptResponse^>(gcnew InvalidOperationException("Browser instance is null. Check CanExecute before calling this method.")); | ||
| 31 | 31 | } | |
| 32 | 32 | ||
| 33 | 33 | auto browserWrapper = static_cast<CefBrowserWrapper^>(browser); | |
| 34 | - auto javascriptNameConverter = GetJavascriptNameConverter(); | ||
| 35 | - | ||
| 36 | - auto doneCallback = _pendingTasks->CreateJavascriptCallbackPendingTask(_callback->Id, timeout); | ||
| 37 | - | ||
| 38 | - auto callbackMessage = CefProcessMessage::Create(kJavascriptCallbackRequest); | ||
| 39 | - auto argList = callbackMessage->GetArgumentList(); | ||
| 40 | - SetInt64(argList, 0, doneCallback.Key); | ||
| 41 | - SetInt64(argList, 1, _callback->Id); | ||
| 42 | - auto paramList = CefListValue::Create(); | ||
| 43 | - for (int i = 0; i < parameters->Length; i++) | ||
| 44 | - { | ||
| 45 | - auto param = parameters[i]; | ||
| 46 | - SerializeV8Object(paramList, i, param, javascriptNameConverter); | ||
| 47 | - } | ||
| 48 | - argList->SetList(2, paramList); | ||
| 49 | 34 | ||
| 50 | 35 | auto frame = browserWrapper->Browser->GetFrameByIdentifier(StringUtils::ToNative(_callback->FrameId)); | |
| 51 | 36 | ||
| 52 | 37 | if (frame.get() && frame->IsValid()) | |
| 53 | 38 | { | |
| 39 | + auto javascriptNameConverter = GetJavascriptNameConverter(); | ||
| 40 | + | ||
| 41 | + auto doneCallback = _pendingTasks->CreateJavascriptCallbackPendingTask(_callback->FrameId, _callback->Id, timeout); | ||
| 42 | + | ||
| 43 | + auto callbackMessage = CefProcessMessage::Create(kJavascriptCallbackRequest); | ||
| 44 | + auto argList = callbackMessage->GetArgumentList(); | ||
| 45 | + SetInt64(argList, 0, doneCallback.Key); | ||
| 46 | + SetInt64(argList, 1, _callback->Id); | ||
| 47 | + auto paramList = CefListValue::Create(); | ||
| 48 | + for (int i = 0; i < parameters->Length; i++) | ||
| 49 | + { | ||
| 50 | + auto param = parameters[i]; | ||
| 51 | + SerializeV8Object(paramList, i, param, javascriptNameConverter); | ||
| 52 | + } | ||
| 53 | + argList->SetList(2, paramList); | ||
| 54 | + | ||
| 54 | 55 | frame->SendProcessMessage(CefProcessId::PID_RENDERER, callbackMessage); | |
| 55 | 56 | ||
| 56 | 57 | return doneCallback.Value->Task; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,6 +8,7 @@ | |||
| 8 | 8 | using System.Text; | |
| 9 | 9 | using System.Threading.Tasks; | |
| 10 | 10 | using Bogus; | |
| 11 | + using CefSharp.Example; | ||
| 11 | 12 | using Xunit; | |
| 12 | 13 | using Xunit.Abstractions; | |
| 13 | 14 | using Xunit.Repeat; | |
@@ -26,6 +27,61 @@ public EvaluateScriptAsyncTests(ITestOutputHelper output, CefSharpFixture collec | |||
| 26 | 27 | this.collectionFixture = collectionFixture; | |
| 27 | 28 | } | |
| 28 | 29 | ||
| 30 | + [Fact] | ||
| 31 | + public async Task V8Context() | ||
| 32 | + { | ||
| 33 | + Task evaluateCancelAfterDisposeTask; | ||
| 34 | + using (var browser = new CefSharp.OffScreen.ChromiumWebBrowser(automaticallyCreateBrowser: false)) | ||
| 35 | + { | ||
| 36 | + await browser.CreateBrowserAsync(); | ||
| 37 | + | ||
| 38 | + // no V8 context | ||
| 39 | + await Assert.ThrowsAsync<Exception>(() => browser.EvaluateScriptAsync("1+1")); | ||
| 40 | + | ||
| 41 | + Task evaluateWithoutV8ContextCancelTask; | ||
| 42 | + Task<int> evaluateWithoutV8ContextTask; | ||
| 43 | + using (var frame = browser.GetMainFrame()) | ||
| 44 | + { | ||
| 45 | + evaluateWithoutV8ContextTask = frame.EvaluateScriptAsync<int>("1+2"); | ||
| 46 | + evaluateWithoutV8ContextCancelTask = frame.EvaluateScriptAsync("new Promise(resolve => setTimeout(resolve, 1000))"); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + // V8 context | ||
| 50 | + await browser.LoadUrlAsync(CefExample.HelloWorldUrl); | ||
| 51 | + var evaluateCancelAfterV8ContextChangeTask = browser.EvaluateScriptAsync("new Promise(resolve => setTimeout(resolve, 1000))"); | ||
| 52 | + | ||
| 53 | + Assert.Equal(3, await evaluateWithoutV8ContextTask); | ||
| 54 | + Assert.Equal(4, await browser.EvaluateScriptAsync<int>("1+3")); | ||
| 55 | + | ||
| 56 | + // change V8 context | ||
| 57 | + await browser.LoadUrlAsync(CefExample.HelloWorldUrl); | ||
| 58 | + evaluateCancelAfterDisposeTask = browser.EvaluateScriptAsync("new Promise(resolve => setTimeout(resolve, 1000))"); | ||
| 59 | + | ||
| 60 | + Assert.Equal(5, await browser.EvaluateScriptAsync<int>("1+4")); | ||
| 61 | + | ||
| 62 | + await Assert.ThrowsAsync<TaskCanceledException>(() => evaluateCancelAfterV8ContextChangeTask); | ||
| 63 | + await Assert.ThrowsAsync<TaskCanceledException>(() => evaluateWithoutV8ContextCancelTask); | ||
| 64 | + } | ||
| 65 | + await Assert.ThrowsAsync<TaskCanceledException>(() => evaluateCancelAfterDisposeTask); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + [Fact] | ||
| 69 | + public async Task CancelEvaluateOnOOM() | ||
| 70 | + { | ||
| 71 | + await Assert.ThrowsAsync<TaskCanceledException>(() => Browser.EvaluateScriptAsync( | ||
| 72 | + @" | ||
| 73 | + let array1 = []; | ||
| 74 | + for (let i = 0; i < 10000000; i++) { | ||
| 75 | + let array2 = []; | ||
| 76 | + for (let j = 0; j < 10000000; j++) { | ||
| 77 | + array2.push('a'.repeat(100000000)); | ||
| 78 | + } | ||
| 79 | + array1.push(array2); | ||
| 80 | + } | ||
| 81 | + " | ||
| 82 | + )); | ||
| 83 | + } | ||
| 84 | + | ||
| 29 | 85 | [Theory] | |
| 30 | 86 | [InlineData(double.MaxValue, "Number.MAX_VALUE")] | |
| 31 | 87 | [InlineData(double.MaxValue / 2, "Number.MAX_VALUE / 2")] | |
@@ -264,7 +320,7 @@ public async Task CanEvaluateScriptAsyncReturnArrayBuffer(int iteration) | |||
| 264 | 320 | ||
| 265 | 321 | var randomizer = new Randomizer(); | |
| 266 | 322 | ||
| 267 | - var expected = randomizer.Utf16String(minLength: iteration, maxLength:iteration); | ||
| 323 | + var expected = randomizer.Utf16String(minLength: iteration, maxLength: iteration); | ||
| 268 | 324 | var expectedBytes = Encoding.UTF8.GetBytes(expected); | |
| 269 | 325 | ||
| 270 | 326 | var javascriptResponse = await Browser.EvaluateScriptAsync($"new TextEncoder().encode('{expected}').buffer"); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments