[C#] Метод Invoke

nik93

Читал чужой код и наткнулся на вот такое
private object FilterValue
{
get
{
object result = null;

switch (FilterType)
{
case FilterType.None:
case FilterType.GroupName:
case FilterType.GroupMemberName:
this.InvokeEventHandler)delegate
{
result = "%" + this.textBoxFilterValue.Text + "%";
});
break;

в чем смысл Invoke, почему нельзя было просто написать
 case FilterType.GroupMemberName:
result = "%" + this.textBoxFilterValue.Text + "%";
break;

Alexander08

мля, ну зачем такие вопросы в форум? ну хоть бы мсдн почитал, чтоль?

nik93

я читал - не понял зачем именно в ЭТОМ месте он применяется.
Впринципе знал что такая реакция последует, но куда мне еще писать :(
ЗЫ: Если такие посты сильно напрягаю, создайте раздел "Для ламеров", думаю не помешает.

freezer

Я думаю, в данном случае (контрол TextBox) этот Invoke не нужен, потому что запрашивание текста из другого потока для этого контрола - не криминал. А вот всякие DataGrid'ы, деревья и т.п. без Invoke то ли исключения кидают, то ли в дедлок уходят

nik93

т.е. это у прогера "стиль" такой?

njvfc1

Control.Invoke Method (Delegate)
 
Executes the specified delegate on the thread that owns the control's underlying window handle.
А по-моему Invoke здесь нужен. Криминала конечно без него нет, но с ним правильней имхо.
 
 

freezer

просто очень правильный чувак ;)
он наверное ещё и все исключения ловит и на них пишет Trace.WriteLine ;)

nik93

с ним правильней имхо.
а можешь пояснить в чем "правильность" именно в этом конкретном примере?
Я например не могу ее уловить, согласен с - человек очень правильный и так привык :) .

freezer

а можешь пояснить в чем "правильность" именно в этом конкретном примере?
правильность в том, что в какой-нибудь mono под embedded linux, который крутится на интеллектуальной зубочистке, без Invoke может и не сработаеть ;)

Dasar

потому что запрашивание текста из другого потока для этого контрола - не криминал.
не понятно откуда это следует.
в msdn-е стандартная приписка:
Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Dasar

А вот всякие DataGrid'ы, деревья и т.п. без Invoke то ли исключения кидают, то ли в дедлок уходят
Т.е. попробовал дернуть textBox.Text из другой потока, ничего не упало - поэтому можно так делать?
странный подход....

freezer

Мы же ведь весь код не видели. Может быть там это поле только во время инициализации меняется. Или этот метод вызывается из обработчика гуёвого события.
Да и в худшем случае там только кусок строки придёт, если между GetWindowTextLength и GetWindowText кто-то внезапно много буков вставит

Dasar

> Да и в худшем случае там только кусок строки придёт, если между GetWindowTextLength и GetWindowText кто-то внезапно много буков вставит
а если наоборот? уберет,
или исходный код функции TextBox.Text в какой-нибудь патче или версии .net-а поменяется...

freezer

это общий код Control.WindowText:

int windowTextLength = SafeNativeMethods.GetWindowTextLength(new HandleRef(this.window, this.Handle;
if (SystemInformation.DbcsEnabled)
{
windowTextLength = (windowTextLength * 2) + 1;
}
StringBuilder lpString = new StringBuilder(windowTextLength + 1);
UnsafeNativeMethods.GetWindowText(new HandleRef(this.window, this.Handle lpString, lpString.Capacity);
return lpString.ToString;

если уберёт - никаких проблем не будет

nik93

Спасибо Атиле, благодаря ему разрюхал субж.
Respect
там действительно много потоков лезут в этот текстбокс.

kokoc88

UnsafeNativeMethods.GetWindowText(new HandleRef(this.window, this.Handle lpString, lpString.Capacity);
Ровно перед вызовом этого метода я могу грохнуть это окно.

freezer

будет пустая строка, а эта функция ввернёт нуль (результат .NET все равно не проверяет, как видно)

Dasar

PropertyStore тоже считается, что он thread safe?

bleyman

Я не уверен, конечно, но мне в какой-то момент показалось, что во втором дотнете все (или многие) методы Form (или Control) в дебаге тупо кидают эксепшен, если их вызвали из другого треда. То есть я пару раз словил, после чего решил перестать делать вид, что я самый умный, и начать всегда делать Invoke, не проверяя, вдруг какой-то конкретный метод не вылетает. Не вижу смысла экономить процессорные циклы в данном случае.
Помимо совсем фатальных ошибок могут случиться ещё разные другие, логические и труднообнаруживаемые, типа текст окажется в каком-то промежуточном состоянии (относительно, например, текста в другом текстбоксе). Не понимаю, кстати, бурной радости насчёт того, что если текст удлиннился, то вернётся обрезанный кусок. Лучше бы вылетело по-моему.
А ещё, теоретически там может быть Чорная Магия с event queue. Типа раньше асинхронно вызвали какой-нибудь метод, а теперь вызываем другой и тот обязан вызваться раньше. Так делать нельзя, конечно, но иногда приходится.

freezer

ладно, у нас по-моему тема не туда ушла. Тут уже речь идёт о потоконебезопасности объектов. То есть объект меняется и читается одновременно. В принципе, если ты обложишь объект lock'ами или ReadWriteLocker'ами, этого можно избежать. Но к некоторым объектам (типа того же Grid, или GL-ного контекста) с объектом можно работать только в потоке, которые его породил, и тут уже никакими механизмами синхронизации этого не исправишь.
Оставить комментарий
Имя или ник:
Комментарий: