Работающий проект удаленного взаимодействия .net создает исключение System.Reflection.TargetInvocationException при отладке. - PullRequest
0 голосов
/ 29 марта 2011

У меня есть клиентское серверное приложение с активированным удаленным клиентом .NET.Я использую Visual Studio 2010, ориентируясь на .NET Framework 4. Когда я запускаю без отладки, программа работает нормально - клиенты не могут подключиться без проблем.Но когда я пытаюсь отладить, в строке в клиентском коде, где у меня есть оператор 'new', сервер (я думаю) выдает исключение.

Я хочу сохранить ссылки на удаленные объекты, созданные в коде сервера.Итак, в конструкторе моего Remote Object у меня есть эта строка:

Cache.GetInstance().addFireFighter(this);

Когда я отлаживаю, этот код тоже работает нормально.Но когда он возвращается к строке удаленного объекта, чтобы вызвать метод addFireFighter, именно тогда он падает.Вот метод addFireFighter:

public static IServer _server;

public void addFireFighter(FireFighter ff)
{
    _server.addFireFighter(ff);
}

И метод _server.addFireFighter:

public void addFireFighter(FireFighterResponder.FireFighter ff)
{
    _ffList.Add(ff); // -> works fine :S
    Console.WriteLine("FireFighterResponder addFireFighter added");
    lstBox.Items.Add(ff); //-> CRASH!!
}

Замечание: Когда я запускаю сервер без отладки, но запускаю клиент в режиме отладки, онвсе еще работает нормально.

Это школьный проект, и я новичок в C # .NET remoting.Я реализовал то же самое в Java и не было никаких проблем.Так что я могу дать весь свой проект, если кто-то захочет посмотреть на него.Возможно, у меня есть недостаток дизайна.

Вот трассировка стека:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Cross-thread operation not valid: Control 'lstBox' accessed from a thread other than the thread it was created on.
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.ListBox.NativeAdd(Object item)
   at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object item)
   at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item)
   at FirefighterMonitorSystem.BaseStation.addFireFighter(FireFighter ff) in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FirefighterMonitorSystem\BaseStation.cs:line 35
   at FireFighterResponder.Cache.addFireFighter(FireFighter ff) in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FireFighterResponder\Cache.cs:line 33
   at FireFighterResponder.FireFighter..ctor() in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FireFighterResponder\FireFighter.cs:line 20
   --- End of inner exception stack trace ---

lstBox - это .NET ListBox в коде моего сервера, где я добавляю каждый удаленный объект.Но меня все еще смущает, почему он работает, когда не в режиме отладки.

Ответы [ 2 ]

1 голос
/ 29 марта 2011

Вы должны взглянуть на свойство InnerException исключения, чтобы узнать, что на самом деле пошло не так.

Вы получаете доступ к элементу управления из потока другого , чем основной поток (также известный как поток пользовательского интерфейса).Это незаконно, окна не являются потокобезопасными.Вы должны использовать Control.Begin / Invoke ().Вы не получите исключение без отладчика, потому что эта проверка потока включена только по умолчанию, когда отладчик подключен.Это не означает, что запуск кода без отладчика безопасен, он случайным образом вызовет проблемы с рисованием или тупик, хотя вам, возможно, придется подождать день или неделю, чтобы это произошло.

0 голосов
/ 29 марта 2011

Исключением, которое выдается, является «Managed Debug Assistant»
Это происходит только тогда, когда отладчик подключен и пытается предупредить вас, что вы делаете что-то не так, что будет работать большую часть времени.
В этом случае вы неправильно обращаетесь к элементу управления lstBox из потока, отличного от того, который его создал.(Windows Forms не поточнобезопасны)

Я не очень хорошо понимаю ваш вопрос, но я думаю, что у вас есть метод в объекте на стороне сервера, который вызывает объект на клиенте.Это означает, что код, работающий на клиенте, выполняется в потоке пула потоков, который обслуживает инфраструктуру удаленного взаимодействия, а не в основном потоке вашего приложения, следовательно, возникает ошибка.

вопрос об этой ошибке и методе Invoke (который выбудет использоваться для исправления), много раз спрашивался раньше, вот одна операция с несколькими потоками недопустима: доступ к элементу управления из потока, отличного от потока, который был создан на , посмотрите, я нехочу сделать всю свою домашнюю работу для вас.:)

Одно предупреждение.Если поток вашего приложения все еще ожидает ответа сервера, и вы пытаетесь использовать Invoke, то ваше приложение, вероятно, зависнет.Например, вы не можете делать это, клиентское приложение вызывает метод сервера foo, метод сервера foo вызывает панель методов клиента. Панель методов клиента использует Invoke для вызова зависания метода клиента

. Теперь вызов Invoke ожидает основной поток, которыйожидает завершения вызова Foo, который ожидает завершения вызова bar, который ожидает завершения Invoke, ожидающего освобождения основного потока, что означает ожидание завершения вызова Foo и т. д...

...