Страницы: 1
Требуется пустить в бекграунде новый поток. Сделал как описано здесь: https://developer.mozilla.org/en/Code_snippets/Threads
Все работает, но при первой попытке обратиться из потока к DOM, браузер сразу вешается. Что собственно логично, и об этом на этой странице написано.
Копаю дальше, нахожу такую статью: http://forums.mozillazine.org/viewtopic.php?p=2431475&sid=7ed44ffe653b76ee4738f37eb6b07ad0
т.е. можно синхронизировать поток в основным через nsIProxyObjectManager. но тут как я понимаю описан старый механизм, "@mozilla.org/event-queue-service;1" уже нету, "@mozilla.org/thread;1" тоже.
Кто подскажет аналог для современного браузера?
Отсутствует
Вот, например:
var b = document. getElementById ("custombuttons-button17"); var proxyObjectManager = Components.classes["@mozilla.org/xpcomproxy;1"] .getService(Components.interfaces.nsIProxyObjectManager); var proxyType = proxyObjectManager.INVOKE_ASYNC | proxyObjectManager.FORCE_PROXY_CREATION; var thread = Components.classes["@mozilla.org/thread-manager;1"] .getService(Components.interfaces.nsIThreadManager) .newThread(0); var po = proxyObjectManager.getProxyForObject (null, Components.interfaces.nsIDOMElement, b, proxyType); // po = b; // crash test var fun = (function (elt) { return function (s) { elt. setAttribute ("label", s); }; }) (po); var backgroundTask = { run: function() { var i, j, s = "a"; for (i = 0; i < 3; i++) { fun (s); for (j = 0; j < 10000000; j++) { j = (j + 1) - 1; } s += "a"; } } } thread.dispatch(backgroundTask, thread.DISPATCH_NORMAL);
Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!
Отсутствует
эмм.. работает, но немного не так как я ожидал. подскажите, а это вообще реально, чтобы из дочернего потока можно было выполнить такие команды как например alert("blabla") или gBrowser.contentWindow.location = "http://google.com" ?
вот например я из потока получаю элемент <input type="text">, находящийся на открытой странице браузера, и ставлю ему element.value = "hello". запускаю, значение элемента меняется на hello, но сразу после этого браузер повисает. то же самое с alert и window.location. может я зря мучаюсь, пытаясь найти решение, и такое взаимодействие между потоками невозможно?
Отсутствует
значение элемента меняется на hello, но сразу после этого браузер повисает. то же самое с alert и window.location.
По моим наблюдениям - зависает не всегда.
Зависания, возможно, происходят из-за того, что проксированный объект в какой-то момент перестает существовать (страница, например, обновилась - визуально объект тот же, но старого, для которого создавался прокси, уже нет).
Или, может быть, из-за ASYNC флага.
Еще можно попробовать выполнять нужные действия из основного потока, передавая дочернему потоку объект основного, что-то вроде:
var proxyObjectManager = Components.classes["@mozilla.org/xpcomproxy;1"] .getService(Components.interfaces.nsIProxyObjectManager); var proxyType = proxyObjectManager.INVOKE_SYNC | proxyObjectManager.FORCE_PROXY_CREATION; var thread = Components.classes["@mozilla.org/thread-manager;1"] .getService(Components.interfaces.nsIThreadManager) .newThread(0); var mto = { QueryInterface: function (iid) { return this; }, observe: function (s, t, d) { gBrowser. contentWindow. location. href = d; } }; var po = proxyObjectManager.getProxyForObject (null, Components.interfaces.nsIObserver, mto, proxyType); var fun = (function (elt) { return function (s) { elt. observe (null, "", s); }; }) (po); var backgroundTask = { run: function() { var i, j, s = "a"; for (i = 0; i < 3; i++) { fun ("http://www.google.com"); for (j = 0; j < 10000000; j++) { j = (j + 1) - 1; } s += "a"; } } } thread.dispatch(backgroundTask, thread.DISPATCH_NORMAL);
Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!
Отсутствует
спасибо за этот вариант, держите в репу. я пытался сам сделать нечто похожее, но что-то не получалось, уже не помню что.
а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?
Отсутствует
а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?
Возможно. Например, backgroundTask реализует интерфейс nsIObserver и, получая глобальное уведомление изменяет внутренний флаг, который периодически проверяется кодом из run ()
Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!
Отсутствует
Страницы: 1