Также упомянутый в "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.
Относительно части «Возможно ли»: Нет, Control.BeginInvoke
использует Windows ' PostMessage ()
, и это означает, что ответа нет. Это также означает, что RefreshRulesDelegate выполняется в основном потоке, а не в фоновом потоке.
Итак, используйте delegate.BeginInvoke
или ThreadPool, а когда они будут завершены, используйте Control. [Begin] Invoke ()
для обновления пользовательского интерфейса.
Вы можете сделать это:
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, вы можете получить документацию о том, как это сделать здесь
Значит, вы хотите, чтобы в рабочем потоке произошла «дополнительная вещь»? (иначе вы бы просто запустили его в методе 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 */ });
});