Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > BeginInvoke: как сразу указать, что делать?


Автор: Dims 22.10.2008, 17:36
В джаве я мог писать:

Код

SwingUtilities.InvokeLater( new Runnable() {
   public void run() {
   ...
   }
});


Как мне так же написать в C#?

А то у меня как-то уж совсем нелепо получается: сперва определяю специальный тип делегата, 

Код

public delegate void Kick();


затем определяю метод с той же сигнатурой 

Код

private void RefreshList()
        {...


и только потом вызваю BeginInvoke

Код

BeginInvoke(new Kick(RefreshList));


Сразу две лишние сущности!

Автор: PashaPash 22.10.2008, 18:29
Dims, 
Код

ThreadPool.QueueUserWorkItem(new WaitCallback(Kick));
или если не хочешь менять сигнатуру:
ThreadPool.QueueUserWorkItem(delegate { ... } );
ThreadPool.QueueUserWorkItem(delegate { Kick(); } );

Автор: yar 22.10.2008, 19:10
C# 3.0:
Код
BeginInvoke(new MethodInvoker( 
        () => {
            MessageBox.Show("dada");
        }
));


C# 2.0:
Код
BeginInvoke(new MethodInvoker( 
        delegate() {
            MessageBox.Show("dada");
        }
));

Автор: Dims 25.10.2008, 21:09
А зачем нужен этод MethodInvoker?

Почему сразу нельзя написать:

BeginInvoke(RefreshList);

В Си++, помнится, если какой-то метод принимал указатель на функцию, ему можно было передать прямо имя этой функции (может, с амперсандом, не помню).


Автор: PashaPash 25.10.2008, 22:19
Dims, BeginInvoke принимает объект типа Delegate, а не указатель. Delegate - абстрактный класс. Автовывода типов делегатов (типа того, что есть для классов и методов) пока нет. Вот и приходится любой неабстрактный тип-наследник Delegate.

Автор: Dims 30.10.2008, 01:14
А вот так будет правильно работать:

Код

for( int i = 0; i<10; ++i ) {
BeginInvoke(new MethodInvoker( 
        delegate() {
            MessageBox.Show(i);
        }
));
}


Мне кажется, что получается так, что ко времени выполнения MessageBox цикл успевает уже пройти несколько итераций и в MessageBox может попасть не первое значение. Это так?

Добавлено через 1 минуту и 44 секунды
Иными словами, если в делегат попадает функция, которая использует значения некоторых переменных, то сохраняются ли эти значения до времени выполнения делегата?

Автор: yar 30.10.2008, 09:21
Dims, Верно. будет использовано то значение, которое существует на момент вызова делегата.
Скорее всего к тому моменту, как начнёт выполнятся MessageBox.Show, цикл уже закончится, и все сообщения будут десятками.

Java нас ограничивает, заставляя объявлять все переменные, на которые замыкается анонимный класс как final, так что если мы напишем что-то вроде следующего, при наличии MyBeginInvoke:

Код
for(int i=0;i <5; i++) {
    MyBeginInvoke( new Runnable() {
        @Override
        public void run() {
            System.out.println(i);    
        }    
    });;
}


То на нас ругнутся, что i должно быть final

Если же в http://bitsofmind.wordpress.com/2008/01/15/future_closures_for_java/, то тут наступит такой же беспредел, как и в С# ;).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)