Полезная информация

Mozilla Россия — свежие версии программ Mozilla, а также масса полезной информации по каждому продукту.

№106-06-2010 22:01:47

LedVisel
Участник
 
Группа: Members
Зарегистрирован: 12-12-2009
Сообщений: 5
UA: Firefox 3.6

Синхронизация потоков

Требуется пустить в бекграунде новый поток. Сделал как описано здесь: 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" тоже.
Кто подскажет аналог для современного браузера?

Отсутствует

 

№206-06-2010 23:49:43

Anton
Участник
 
Группа: Extensions
Откуда: от верблюда
Зарегистрирован: 14-12-2004
Сообщений: 3057
UA: Firefox 3.6
Веб-сайт

Re: Синхронизация потоков

Вот, например:

Выделить код

Код:

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ентов на части порвет !!!

Отсутствует

 

№307-06-2010 00:53:46

LedVisel
Участник
 
Группа: Members
Зарегистрирован: 12-12-2009
Сообщений: 5
UA: Firefox 3.6

Re: Синхронизация потоков

спасибо, именно такой пример нужен был! ;)

Отсутствует

 

№407-06-2010 03:20:57

LedVisel
Участник
 
Группа: Members
Зарегистрирован: 12-12-2009
Сообщений: 5
UA: Firefox 3.6

Re: Синхронизация потоков

эмм.. работает, но немного не так как я ожидал. подскажите, а это вообще реально, чтобы из дочернего потока можно было выполнить такие команды как например alert("blabla") или gBrowser.contentWindow.location = "http://google.com" ?
вот например я из потока получаю элемент <input type="text">, находящийся на открытой странице браузера, и ставлю ему element.value = "hello". запускаю, значение элемента меняется на hello, но сразу после этого браузер повисает. то же самое с alert и window.location. может я зря мучаюсь, пытаясь найти решение, и такое взаимодействие между потоками невозможно?

Отсутствует

 

№507-06-2010 20:41:12

Anton
Участник
 
Группа: Extensions
Откуда: от верблюда
Зарегистрирован: 14-12-2004
Сообщений: 3057
UA: Firefox 3.6
Веб-сайт

Re: Синхронизация потоков

LedVisel пишет

значение элемента меняется на 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ентов на части порвет !!!

Отсутствует

 

№607-06-2010 22:23:10

LedVisel
Участник
 
Группа: Members
Зарегистрирован: 12-12-2009
Сообщений: 5
UA: Firefox 3.6

Re: Синхронизация потоков

спасибо за этот вариант, держите в репу. я пытался сам сделать нечто похожее, но что-то не получалось, уже не помню что.
а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?

Отсутствует

 

№711-06-2010 18:05:32

Anton
Участник
 
Группа: Extensions
Откуда: от верблюда
Зарегистрирован: 14-12-2004
Сообщений: 3057
UA: Firefox 3.6
Веб-сайт

Re: Синхронизация потоков

LedVisel пишет

а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?

Возможно. Например, backgroundTask реализует интерфейс nsIObserver и, получая глобальное уведомление изменяет внутренний флаг, который периодически проверяется кодом из run ()


Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]