Как передать указатель на интерфейс потоку?

Одним из решений может быть создание декартового произведения всех ожидаемых строк с использованием декартового произведения между (фиксированным) списком значений, а затем LEFT JOIN с помощью current_view.

Следующий запрос гарантирует, что вы получите запись для каждого заданного кортежа s_date/part_no/issue_group/s_level. Если в current_view не найдено ни одной записи, запрос отобразит количество 0.

SELECT
    sd.s_date,
    pn.part_no,
    ig.issue_group,
    sl.s_level,
    COALESCE(cv.qty_filled, 0) qty_filled
FROM
    (SELECT '201802' AS s_date UNION SELECT '201803') AS sd
    CROSS JOIN (SELECT 'xxxxx' AS part_no) AS pn
    CROSS JOIN (SELECT '1' AS issue_group UNION SELECT '2') AS ig
    CROSS JOIN (SELECT '80' AS s_level UNION SELECT '100' UNION SELECT 'Late') AS sl
    LEFT JOIN current_view cv 
        ON  cv.s_date      = sd.s_date
        AND cv.part_no     = pn.part_no
        AND cv.issue_group = ig.issue_group
        AND cv.s_level     = ig.s_level
ORDER BY
    sd.s_date,
    pn.part_no,
    ig.issue_group,
    DECODE(sl.s_level, '80', 1, '100', 2, 'Late', 3)

Примечание: вы не пометили свою СУБД. Это должно работать на большинстве из них, за исключением Oracle, где вам нужно добавить FROM DUAL к каждому выбору в запросах, которые перечисляют допустимые значения, например:

(SELECT '201802' AS s_date FROM DUAL UNION SELECT '201803' FROM DUAL) AS sd
6
задан Vinay 4 February 2009 в 15:14
поделиться

3 ответа

Как был указан ниже, передав a COM указатель на интерфейс между потоками в не безопасный.

Принятие Вас знает то, что Вы делаете:

hThread = CreateThread(
                NULL,
                        0,
                        SecondaryThread,
                        (LPVOID) pis8
                        0,
                        &dwGenericThreadID);

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
   ((IS8Simulation*) iValue)->Open();
}

Ориентированная на многопотоковое исполнение версия:

void MainThread()
{
    IStream* psis8;
    HRESULT res = CoMarshalInterThreadInterfaceInStream (IID_IS8SIMULATION, pis8, &psis8);
    if (FAILED(res))
         return;
    hThread = CreateThread(
                NULL,
                0,
                SecondaryThread,
                (LPVOID) psis8
                0,
                &dwGenericThreadID
          );
}

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
   IS8Simulation* pis8;
   HRESULT res = CoGetInterfaceAndReleaseStream((IStream*) iValue, IID_IS8SIMULATION, &pis8);
   if (FAILED(res))
      return (DWORD) res;
   pis8->Open();
}
8
ответ дан 8 December 2019 в 13:50
поделиться

В основном необходимо сделать следующее:

  • CoMashalInterThreadInterfaceInStream ==> Вы получаете интерфейс IStream.
  • передача, которую IStream к потоку, например, поскольку заявил Quassnoi.
  • в SecondaryThread звонить CoGetInterfaceAndReleaseStream получить интерфейс (или прокси к нему, при необходимости).

Не выпускайте интерфейс IStream, если создание сбоев потока, и не выходит из потока, пока yu не звонили CoGetInterfaceAndReleaseStream.

Время выполнения COM создаст прокси для Вас автоматически. Прокси гарантирует, что, например, поточный квартирой COM-компонент назван на потоке, который создал его. Однако это также требует что:

  • Интерфейс является IDispatch, или компоненты прокси/тупиковые регистрируются для интерфейса
  • threadthat создал компонент, имеет цикл сообщения и обрабатывает сообщения
2
ответ дан 8 December 2019 в 13:50
поделиться

Если интерфейс в Вашем вопросе является COM-интерфейсом, подход, данный Quassnoi, не мог бы быть достаточным. Необходимо обратить внимание на модель потоков используемого COM-объекта. Если вторичный поток присоединится к отдельной квартире COM от той, что Ваш COM-объект был создан в, и если тот объект не будет гибким квартирой, то необходимо будет упорядочить тот указатель на интерфейс так, чтобы вторичный поток получил прокси и не прямой указатель на объект.

COM-объект обычно делается гибким квартирой при помощи специальной реализации IMarshal. Самый простой подход должен агрегировать Marshaler Со свободными потоками.

Некоторые полезные ссылки...

Обновление: о Marshaler со свободными потоками...

Это ясно из комментариев к этой теме, что некоторые люди рекомендовали бы никогда не касаться FTM. В то время как "Эффективный COM" является превосходной книгой, я думаю, что некоторые ее рекомендации открыты для интерпретации. Объект 33 говорит, "Остерегаются FTM"; это не говорит, "Никогда не используют FTM". Очень мудро это советует осторожности особенно, когда Ваш гибкий квартирой объект содержит ссылки на другие объекты, потому что они не могли бы быть гибкими квартирой. Таким образом, действительно совет: думайте тщательно при создании гибких квартирой объектов, используют ли они FTM для достижения их гибкости. Если бы Вы уверены, что можно создать гибкий квартирой объект, я не вижу оснований, почему Вы не использовали бы FTM для достижения этого.

7
ответ дан 8 December 2019 в 13:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: