Здравствуйте, Аноним, Вы писали:
А>Код с описанием проблемы: А>
А>var obj = new MyComObject(); // MyComObject - это СOM объект, не мой, поэтому внутреннее устройство его не знаю
А>obj.SomeEvent += () =>
А>{
А> obj.Method(); // при вызове этого метода внутрях что-то блокируется, из-за этого дальше ничего не работает
А>};
А>Thread.Sleep(10000000);
А>
А>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
А COM объект он STA или MTA?
Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 07:07
Оценка:
Код с описанием проблемы:
var obj = new MyComObject(); // MyComObject - это СOM объект, не мой, поэтому внутреннее устройство его не знаю
obj.SomeEvent += () =>
{
obj.Method(); // при вызове этого метода внутрях что-то блокируется, из-за этого дальше ничего не работает
};
Thread.Sleep(10000000);
Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
Здравствуйте, Аноним, Вы писали:
А>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
А кто такой AutoWaitHandle?
Re[2]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 07:24
Оценка:
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Аноним, Вы писали:
А>>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
L>А кто такой AutoWaitHandle?
Долбаный МС-кий найминг конвеншин... AutoResetEvent, который наследник WaitHandle.
Здравствуйте, Аноним, Вы писали:
А>>>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
L>>А кто такой AutoWaitHandle?
А>Долбаный МС-кий найминг конвеншин... AutoResetEvent, который наследник WaitHandle.
WaitOne ждет срабатывания event-а и если "повезет", то поток просыпется. Thread.Sleep-же просто засыпает поток на указанное кол-во милисекунд.
Re[4]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 07:30
Оценка:
Здравствуйте, Lloyd, Вы писали:
L>WaitOne ждет срабатывания event-а и если "повезет", то поток просыпется. Thread.Sleep-же просто засыпает поток на указанное кол-во милисекунд.
Это понятно. Вопрос в способе блокирования. Почему в одному случае в обработчике события происходит блокировка, а в другом случае — нет.
Здравствуйте, Аноним, Вы писали:
L>>WaitOne ждет срабатывания event-а и если "повезет", то поток просыпется. Thread.Sleep-же просто засыпает поток на указанное кол-во милисекунд.
А>Это понятно. Вопрос в способе блокирования. Почему в одному случае в обработчике события происходит блокировка, а в другом случае — нет.
Похоже, _d_m_ на более правилном пути. Уступаю ему слово.
Re[2]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 07:37
Оценка:
Здравствуйте, _d_m_, Вы писали:
А>>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
___>А COM объект он STA или MTA?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
А>>>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
___>>А COM объект он STA или MTA?
А>Как это узнать?
HKCR\CLSID\<CLSID твоего COM объекта>\InprocServer32\
@ThreadingModel=???
Узнать можно в реестре, в регистрации этого COM-объекта по его CLSID. Но Вы-бы лучше показали более полный и реальный код, а также подробности о COM-объекте, так как изложенное Вами пока всё равно плохо согласуетмя с апартаментными моделями.
Здравствуйте, Аноним, Вы писали:
А>Код с описанием проблемы: А>
А>var obj = new MyComObject(); // MyComObject - это СOM объект, не мой, поэтому внутреннее устройство его не знаю
А>obj.SomeEvent += () =>
А>{
А> obj.Method(); // при вызове этого метода внутрях что-то блокируется, из-за этого дальше ничего не работает
А>};
А>Thread.Sleep(10000000);
А>
А>Если Thread.Sleep заменяю на AutoWaitHandle.WaitOne, то все работает. Эти две конструкции по разному блокируют поток?
Вобще с COM-ом надо внимательно быть по поводу потоков. Я в этом вопросе собак наелся. Если что — помогу.
Мой телепатический мозг улавливает эманнации твоего кода, выстрел навскидку:
[STAThread]
static void Main(string[] args)
{
...
var obj = new MyComObject(); // MyComObject - это СOM объект, не мой, поэтому внутреннее устройство его не знаю
obj.SomeEvent += () =>
{
obj.Method();
};
Application.Run(); // запуск очереди сообщений
...
}
или более правильно
static void Main(string[] args)
{
...
var MyThread = new Thread((ThreadStart)delegate
{
var obj = new MyComObject(); // MyComObject - это СOM объект, не мой, поэтому внутреннее устройство его не знаю
obj.SomeEvent += () =>
{
obj.Method();
};
Application.Run(); // запуск очереди сообщений
});
MyThread.SetApartmentState(ApartmentState.STA);
MyThread.Start();
Console.WriteLine("Жми ENTER для выхода...");
Console.ReadLine();
Application.Exit();
}
PS: Как ты будешь отписывать анонимный делегат?
Re[4]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 08:12
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>HKCR\CLSID\<CLSID твоего COM объекта>\InprocServer32\ ___>@ThreadingModel=???
У меня ветка оказалось чутка другой (видимо из-за 64 битности). HKEY_CLASSES_ROOT\Wow6432Node\CLSID\
Там нет такого ключа.
Да, еще такая детать (судя по ответам дальше). Хост — юнит тест, запускаю через R# TaskLoader. Это не WPF и не консоль... Хотя это все не так важно. Важно другое — почему у Thread.Sleep и WaitHandle разные стили блокировки потоков.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>HKCR\CLSID\<CLSID твоего COM объекта>\InprocServer32\ ___>>@ThreadingModel=???
А>У меня ветка оказалось чутка другой (видимо из-за 64 битности). HKEY_CLASSES_ROOT\Wow6432Node\CLSID\
А>Там нет такого ключа.
Ключ: InprocServer32 есть? Если есть, атрибут ThreadingModel там есть?
Re[6]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 08:39
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, _d_m_, Вы писали:
___>>>HKCR\CLSID\<CLSID твоего COM объекта>\InprocServer32\ ___>>>@ThreadingModel=???
А>>У меня ветка оказалось чутка другой (видимо из-за 64 битности). HKEY_CLASSES_ROOT\Wow6432Node\CLSID\
А>>Там нет такого ключа.
___>Ключ: InprocServer32 есть?
Да.
___>Если есть, атрибут ThreadingModel там есть?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>Загадка. Ну открой его в "OLE/COM Object Viewer", там вкладка Implementation
А>Both
Ага, понятно. Значит обе. НО...
1. Не факт, что разрабы не накосячили, и объект будет работать в MTA.
2. В STA он будет работать. Ты ж не создаешь множество объектов, где критично STA-MTA?
3. Твой затык скорее из-за того, что объект не может вызвать событие из-за Thread.Sleep — используй примеры моего кода. Вопросы сюда.
Re[10]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 11:59
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>3. Твой затык скорее из-за того, что объект не может вызвать событие из-за Thread.Sleep — используй примеры моего кода. Вопросы сюда.
Вопрос остался первоначальный. Чем блокировка потока через Sleep отличается от WaitHandle?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>3. Твой затык скорее из-за того, что объект не может вызвать событие из-за Thread.Sleep — используй примеры моего кода. Вопросы сюда.
А>Вопрос остался первоначальный. Чем блокировка потока через Sleep отличается от WaitHandle?
Вероятно, WaitHandle.WaitOne реализуется через MsgWaitForMultipleObjects, что позволяет реагировать на оконные сообщения.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>3. Твой затык скорее из-за того, что объект не может вызвать событие из-за Thread.Sleep — используй примеры моего кода. Вопросы сюда.
А>Вопрос остался первоначальный. Чем блокировка потока через Sleep отличается от WaitHandle?
У меня встречный вопрос: а нах тебе так это интересно? IL DASM тебе в помощь и далее другие дизассемблеры натив кода.
Re[12]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 14:31
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>У меня встречный вопрос: а нах тебе так это интересно? IL DASM тебе в помощь и далее другие дизассемблеры натив кода.
Как зачем? Чтобы не допускать больше таких ошибок и знать, где напортачил... Дизассемблеры не нужны. Я конечно хочу узнать причину, но убивать время на это не буду. Остановлюсь на ответе k.o. Тем более что такое уже раньше обсуждали — http://www.rsdn.ru/forum/dotnet/188895.flat.aspx
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>У меня встречный вопрос: а нах тебе так это интересно? IL DASM тебе в помощь и далее другие дизассемблеры натив кода.
А>Как зачем? Чтобы не допускать больше таких ошибок и знать, где напортачил... Дизассемблеры не нужны. Я конечно хочу узнать причину, но убивать время на это не буду. Остановлюсь на ответе k.o. Тем более что такое уже раньше обсуждали — http://www.rsdn.ru/forum/dotnet/188895.flat.aspx
Да его ответ вероятно правильный — я это чуствую. Но ты бы для начала задумался об потоках и как генерятся события в тех же СOM компонентах — зачастую им нужна очередь сообщений (message pump). Поэтому я привел тебе примеры именно с Application.Run(). Если же это какой-то MTA COM и к примеру использует асинхронные колбэки ОС, то те же Windows.Forms встают колом — т.к. они расчитаны только на STA и требуют в этом случае диспетчизацию через создавший поток.
Re[14]: Thread.Sleep vs WaiHandle
От:
Аноним
Дата:
24.11.10 16:00
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>Да его ответ вероятно правильный — я это чуствую. Но ты бы для начала задумался об потоках и как генерятся события в тех же СOM компонентах — зачастую им нужна очередь сообщений (message pump). Поэтому я привел тебе примеры именно с Application.Run(). Если же это какой-то MTA COM и к примеру использует асинхронные колбэки ОС, то те же Windows.Forms встают колом — т.к. они расчитаны только на STA и требуют в этом случае диспетчизацию через создавший поток.
И что такое апартменты, и что такое маршалинг — все знакомо. Вопрос был о способах блокирования потоков. То, что waithandle не блокирует очередь — для меня новостью стало. День прожил не впустую.
Здравствуйте, k.o., Вы писали:
KO>Вероятно, WaitHandle.WaitOne реализуется через MsgWaitForMultipleObjects, что позволяет реагировать на оконные сообщения.
Почти так. Если верить Joe Duffy, то, начиная с Win 2000, он реализуется через CoWaitForMultipleHandles (в более старых системах — через MsgWait... или просто Wait..., в зависимости от типа апартмента), что позволяет разруливать комовские сообщения во время ожидания. Sleep ничего подобного не делает, само собой.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, _d_m_, Вы писали:
___>>3. Твой затык скорее из-за того, что объект не может вызвать событие из-за Thread.Sleep — используй примеры моего кода. Вопросы сюда.
А>Вопрос остался первоначальный. Чем блокировка потока через Sleep отличается от WaitHandle?
Sleep это не блокировка, а засыпание на указанное время.
В процессе "сна" поток может просыпаться для выполнения APC и I/O completion. см. SleepEx из WinAPI
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.