Из того, что я нашел в C#, для метода Control.Invoke требуется, чтобы вы использовали делегат без входных параметров. Есть ли способ обойти это? Я хотел бы вызвать метод обновления пользовательского интерфейса из другого потока и передать ему строковые параметры.Control.Invoke с входными параметрами
ответ
Какую версию C# вы используете? Если вы используете C# 3.5, вы можете использовать блокировки, чтобы избежать передачи параметров.
С C# 3.5public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult>(this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
return control.InvokeRequired
? (TResult)control.Invoke(func, control)
: func(control);
}
public static void InvokeEx<TControl>(this TControl control,
Action<TControl> func)
where TControl : Control
{
control.InvokeEx(c => { func(c); return c; });
}
public static void InvokeEx<TControl>(this TControl control, Action action)
where TControl : Control
{
control.InvokeEx(c => action());
}
}
Безопасное применение кода теперь становится тривиальной.
this.InvokeEx(f => f.label1.Text = "Hello World");
this.InvokeEx(f => this.label1.Text = GetLabelText("HELLO_WORLD", var1));
this.InvokeEx(() => this.label1.Text = DateTime.Now.ToString());
С C# 2.0 становится менее тривиальной
public class MyForm : Form
{
private delegate void UpdateControlTextCallback(Control control, string text);
public void UpdateControlText(Control control, string text)
{
if (control.InvokeRequired)
{
control.Invoke(new UpdateControlTextCallback(UpdateControlText), control, text);
}
else
{
control.Text = text;
}
}
}
Используя это просто, но вы должны определить более обратные вызовы для нескольких параметров.
this.UpdateControlText(label1, "Hello world");
Я думаю (отлично) подход Самуила может быть выдвинут еще больше:
метод расширения:
public static void ExecuteAsync<TControl>(this TControl control, Action action)
where TControl : Control
{
new Thread(() =>
{
control.Invoke(action);
})
.Start();
}
Код формы:
private void doStuff()
{
this.ExecuteAsync(() =>
{
// Do your stuff in a separate thread
// but having full access to local or instance variables.
// No (visible) threading code needs to be used here.
});
}
В Луки говорит, используйте Control.I nvoke как это ...
Например, в форме:
public delegate void DelegatePassMessages(string name, int value);
public DelegatePassMessages passMessage;
В застройщик:
passMessage = new DelegatePassMessages (this.MessagesIn);
Тогда функция MessagesIn получить данные:
public void MessagesIn(string name, int value)
{
}
Тогда для передачи данных в вашу форму:
formName.Invoke(formName.passMessage, new Object[] { param1, param2});
Нашел элегантный способ для .net 2.0 с анонимными методами, завернутый в делегат MethodInvoker. Таким образом, не нужно постоянно определять собственных делегатов.Пример:
private void InitUI(Guid id, string typename)
{
MethodInvoker inv = delegate{tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename);};
tvMatrix.Invoke(inv);
}
Почему не
tvMatrix.Invoke((MethodInvoker) (() => {
tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename);
}));
Некоторые больше возможностей:
this.Invoke(new MethodInvoker(() => this.DoSomething(param1, param2)));
или
this.Invoke(new Action(() => this.DoSomething(param1, param2)));
или даже
this.Invoke(new Func<YourType>(() => this.DoSomething(param1, param2)));
, где первый вариант является лучшим, потому что MethodInvoker разработан для этих целей и имеет лучшую производительность.
Здесь вы используете лямбда-выражения с расширением Invoke() + входным параметром.
Использование: действие (STARS дБ)
_ccb.GetImagerFRU_PartNbr().Invoke(new Action<STARS>(dbase => _ccb.GetImagerFRU_PartNbr().Text = dbase.PartNumber(serial) ?? String.Empty), db);
private void ppTrace(string tv)
{
if (_Txb1.InvokeRequired)
{
_Txb1.Invoke((Action<string>)ppTrace, tv);
}
else
{
_Txb1.AppendText(tv + Environment.NewLine);
}
}
- 1. Функция с общими входными параметрами
- 2. F # Функция Композиция с несколькими входными параметрами
- 3. Сохраненная процедура с входными и выходными параметрами
- 4. Maven: как скомпилировать проект с входными параметрами
- 5. Swift - компилировать программу с входными параметрами
- 6. Фильтры Kalman с четырьмя входными параметрами
- 7. Использование задачи с входными параметрами и результатом
- 8. XMLHTTPтреки в Javascript/PHP с входными параметрами
- 9. Работа Amazon EMR с несколькими входными параметрами
- 10. Запуск .exe с изменяющимися входными параметрами
- 11. Процедура Sql с двумя входными параметрами
- 12. PHP, MySql хранимых процедур с входными параметрами
- 13. Пандит политика с двумя входными параметрами
- 14. $ .when с динамическими входными параметрами и аргументами
- 15. Начальные проблемы со многими входными параметрами
- 16. разницы между делегатом {} и (входными параметрами) => {}
- 17. Вызов хранимой процедуры с использованием EF с выбранными входными параметрами
- 18. Тупик с использованием Control.Invoke?
- 19. control.invoke с параметром out
- 20. Control.Invoke() stucks
- 21. ASP.NET mvc anchor tag helper с двумя входными параметрами
- 22. Создание исполняемой программы из источников Java с входными параметрами
- 23. как перегрузить два метода с различными входными параметрами
- 24. как вызвать метод с несколькими входными параметрами в другом методе
- 25. нужно, чтобы получить правильный синтаксис яваскрипта с входными параметрами
- 26. любой способ передать функцию с 2 входными параметрами в java?
- 27. Метод модульного тестирования с входными параметрами из нескольких таблиц данных
- 28. C++ 11 thread pool - задачи с входными параметрами
- 29. Объявление функциональных литералов с общими входными параметрами в Kotlin
- 30. Функция вызова с изменяющимися входными параметрами в цикле Matlab