Очередь вызовов методов - есть идеи как? - PullRequest
12 голосов
/ 05 мая 2010

Я пишу сильно асинхронное приложение.

Я ищу способ ставить в очередь вызовы методов, аналогично тому, что делает BeginInvoke / EndInvoke .... но в моей собственной очереди.Причина в том, что у меня есть собственная оптимизированная система очередей сообщений, использующая пул потоков, но в то же время я проверяю, чтобы каждый компонент был однопоточным в запросах (т. Е. Один поток обрабатывает только сообщения для компонента).

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

Кто-нибудь знает способ перехвата вызова метода?Какой-то способ использовать TransparentProxy / Virtual Proxy для этого?;) Обслуживаемый компонент?Я хотел бы, чтобы это было как можно меньше накладных расходов;)

Ответы [ 3 ]

13 голосов
/ 05 мая 2010

Как насчет использования лямбды?

Я имею в виду, почему бы вам не создать какую-то очередь и обработать ее так, как

while (!queue.Empty) 
{
    Action action = queue.Pop();
    action(); // this calls your action
}

Вы можете добавить действия очень просто:

Queue.Add( ()=>{  /* any code you wish here */})

Это всего лишь совет, я не уверен, есть ли какой-нибудь класс Queue, но было бы довольно просто создать его (и поточно-ориентированный!) Самостоятельно.

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

Pz, разработчик TaskConnect

2 голосов
/ 20 ноября 2014

Создать очередь из MethodInvoker

Queue<MethodInvoker> EventCall = new Queue<MethodInvoker>();

Позже добавьте элементы в свою очередь

EventCall.Enqueue(ClearAllVals);
EventCall.Enqueue(saystuff);
EventCall.Enqueue(testFunc);

Затем вызывайте ваши функции по одному:

MethodInvoker bb = EventCall.Dequeue();
bb();
bb = EventCall.Dequeue();
bb();
bb = EventCall.Dequeue();
bb();

для безопасного вызова всех ваших функций (это также удалит их все из очереди, оставив очередь пустой и все вызванные функции)

public bool InvokeAll(){
    MethodInvoker bb = null; // this will hold the function prior to use
    for(int i = 0; i<EventCall.count; i++){

        bb = EventCall.Dequeue(); //pull a method off of the queue
        bb(); //call the method you pulled off of the queue

    }
}

чтобы позвонить им всем, просто используйте InvokeAll(); или позвоните им один раз, когда захотите:

public bool NextEvent(){
    MethodInvoker bb = null; // this will hold the function prior to use
    if(EventCall.count > 0){

        bb = EventCall.Dequeue(); //pull a method off of the queue
        bb(); //call the method you pulled off of the queue

        } else {
        MessageBox.Show("there was no event to call"); // this is optional, point being you should be handeling the fact that there is no events left in some way.
        }
}
1 голос
/ 05 мая 2010

DynamicProxy, который является частью проекта Castle, позволяет перехватывать элементы объекта без какой-либо типичной маршальной боли

http://www.castleproject.org/projects/dynamicproxy/

Вы можете использовать это для перехвата вызовов ваших методов, а затем делать с ними то, что вы хотите.

...