Как я делегирую метод AsyncCallback для Управления. BeginInvoke? (.NET)

Также упомянутый в "JavaScript Crockford: Хорошие Части":

parseInt() опасно. При передаче его строка, не сообщая ему о надлежащей основе, это может возвратить неожиданные числа. Например parseInt('010') возвраты 8, не 10. Передача основы к parseInt заставляет его работать правильно:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.
5
задан Sheed 30 November 2009 в 12:00
поделиться

3 ответа

Относительно части «Возможно ли»: Нет, Control.BeginInvoke использует Windows ' PostMessage () , и это означает, что ответа нет. Это также означает, что RefreshRulesDelegate выполняется в основном потоке, а не в фоновом потоке.

Итак, используйте delegate.BeginInvoke или ThreadPool, а когда они будут завершены, используйте Control. [Begin] Invoke () для обновления пользовательского интерфейса.

4
ответ дан 14 December 2019 в 13:38
поделиться

Вы можете сделать это:

this.BeginInvoke(delegate
{
    RefreshRules(ctrl, ctrl.DsRules, ctrl.CptyId);
    RefreshCompleted();
});

РЕДАКТИРОВАТЬ:

Я бы подумал об удалении аргумента IAsyncResult из метода RefreshCompleted и использовал решение выше.

Если по какой-то причине вам действительно нужно чтобы сохранить аргумент IAsyncResult. Вы можете реализовать метод расширения для Control:

public static IAsyncResult BeginInvoke(this Control control, Delegate del, object[] args, AsyncCallback callback, object state)
{
    CustomAsyncResult asyncResult = new CustomAsyncResult(callback, state);
    control.BeginInvoke(delegate
    {
        del.DynamicInvoke(args);
        asyncResult.Complete();
    }, args);

    return asyncResult;
}

public static void EndInvoke(this Control control, IAsyncResult asyncResult)
{
    asyncResult.EndInvoke();
}

Вам нужно будет определить свой класс CustomAsyncResult, вы можете получить документацию о том, как это сделать здесь

2
ответ дан 14 December 2019 в 13:38
поделиться

Значит, вы хотите, чтобы в рабочем потоке произошла «дополнительная вещь»? (иначе вы бы просто запустили его в методе RefreshRules ). Возможно, просто используйте ThreadPool.QueueUserItem :

ThreadPool.QueueUserWorkItem(delegate { /* your extra stuff */ });

в конце (или после) вашего метода RefreshRules ?

Для информации вам может быть проще / аккуратнее вызвать BeginInvoke также с анонимным методом:

this.BeginInvoke((MethodInvoker) delegate {
    RefreshRules(ctrl, ctrl.DsRules, ctrl.CptyId);
    ThreadPool.QueueUserWorkItem(delegate { /* your extra stuff */ });
});

это позволяет избежать создания типа делегата и обеспечивает проверку типов при вызове RefreshRules - обратите внимание, что он захватывает ctrl , хотя - поэтому, если вы находитесь в цикле, вам понадобится копия:

var tmp = ctrl;
this.BeginInvoke((MethodInvoker) delegate {
    RefreshRules(tmp, tmp.DsRules, tmp.CptyId);
    ThreadPool.QueueUserWorkItem(delegate { /* your extra stuff */ });
});
0
ответ дан 14 December 2019 в 13:38
поделиться
Другие вопросы по тегам:

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