Вызовите делегата на определенный поток C#

Там какой-либо путь состоит в том, чтобы заставить делегата работать на определенном потоке?

Скажите, что я имею:

CustomDelegate del = someObject.someFunction;
Thread dedicatedThread = ThreadList[x];

Я могу иметь последовательный фон длительный поток и вызвать моих собственных делегатов на него каждый раз, когда мне нужен он. Это должен быть тот же поток каждый раз.

[Править]

Причина, почему я хочу, чтобы это было на специализированном потоке, время, то, что я inten, чтобы выполнить делегата на нем и приостановить поток после y миллисекунды и резюме поток, когда я выполняю другого делегата на нем. Я вижу, что это не возможно. Я буду иметь очередь делегата и позволю основной функции чтения потока и выполнения от него.

Для разъяснения с конкретным примером у меня есть игровая система с набором потоков плеера. Я хотел бы, чтобы каждый playerthread выполнил обработчики событий для игровых событий на нем. Если бы обработчики событий занимают слишком много времени, я хотел бы смочь приостановить тот конкретный плеер до следующего события путем приостановки его потока.

Таким образом имея специализированный поток, на котором я могу выполнить несколько обработчиков событий, я могу приостановить AI конкретного игрока в случае, если это стало с ошибками или занимает слишком много времени.

10
задан Rob 13 August 2010 в 23:01
поделиться

4 ответа

Я думаю, что лучшим решением будет использовать объекты Task и поставить их в очередь в StaThreadScheduler , выполняющем один нить.

В качестве альтернативы можно использовать ActionThread в Nito.Async для создания обычного потока со встроенной очередью делегатов Action .

Однако ни один из них не решит напрямую другую потребность: возможность «приостановить» одно действие и продолжить другое. Для этого вам нужно разбрасывать «точки синхронизации» на каждое действие и иметь способ сохранить его состояние, повторно поставить его в очередь и продолжить выполнение следующего действия.

Вся эта сложность почти приближается к системе планирования потоков, поэтому я рекомендую сделать шаг назад и провести еще одну переделку. Вы можете поставить каждое действие в очередь на ThreadPool (я рекомендую, чтобы каждое из них было только объектом Task ). Вам все равно нужно будет добавить «точки синхронизации», но вместо того, чтобы сохранять состояние и повторно ставить их в очередь, вам просто нужно приостановить (заблокировать) их.

3
ответ дан 4 December 2019 в 03:15
поделиться

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

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

Если окажется, что пул потоков подходит для выполнения вашего кода, вы всегда можете использовать для этого метод BeginInvoke делегата:

// wrap your custom delegate in an action for simplicity ...
Action someCode = () => yourCustomDelegate( p1, p2, p3, ... );
// asynchronously execute the currying Action delegate on the threadpool...
someCode.BeginInvoke( someCode.EndInvoke, action );
1
ответ дан 4 December 2019 в 03:15
поделиться

К сожалению, на самом деле нет ничего встроенного для этого ни в одном универсальном потоке. Вы можете добиться этого, создав класс, который является оболочкой для Thread и реализует ISynchonizeInvoke.

Простым подходом является создание очереди обработки событий в выделенном потоке, как упоминает Л.Бушкин. Я предлагаю использовать класс Queue и напрямую вызывать делегат Action. Вы можете выполнить большинство задач, которые вам могут понадобиться, с помощью действий анонимного делегата.

Наконец, в качестве предупреждения я предлагаю вам использовать Semaphore или EventWaitHandle вместо Thread.Sleep в вашем выделенном потоке. Это определенно более дружелюбно, чем повторять фоновый цикл снова и снова, когда в этом нет необходимости.

2
ответ дан 4 December 2019 в 03:15
поделиться

Для создаваемых вами потоков вы можете указать делегат ThreadStart только при их создании. Нет никаких условий для внедрения другого делегата в созданный поток. Пул потоков отличается тем, что позволяет отправлять делегатов в ранее созданные потоки, которые он запускает от вашего имени.

Непонятно, какую проблему вы пытаетесь решить. Чего вы пытаетесь достичь (или избежать), пытаясь запустить несколько делегатов в одном потоке?

0
ответ дан 4 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

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