2011-03-29 66 views
0

我有一個.NET遠程處理客戶端激活對象類型客戶端服務器應用程序。我正在使用面向.NET Framework 4的Visual Studio 2010。當我在沒有調試的情況下運行時,程序工作正常 - 客戶端可以連接沒有問題。但是當我嘗試調試時,在客戶端代碼中有'new'操作符的行中,服務器(我認爲)會引發異常。工作.net遠程處理項目調試時拋出System.Reflection.TargetInvocationException

我想要做的是保持對在服務器代碼中創建的遠程對象的引用。所以在我的遠程對象的構造函數中我有這樣一行:

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遠程處理新手。我在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在我的服務器代碼,我添加的每個遠程對象。但是我仍然困惑的是爲什麼它不在調試模式時工作。

+0

很遺憾你的學校落後於時代。 .NET Remoting已被棄用,以支持WCF。 – 2011-03-29 18:51:15

回答

1

您必須查看異常的InnerException屬性才能知道發生了什麼錯誤。

您正在訪問的線程控制其他比主線程(又名UI線程)。這是非法的,Windows不是線程安全的。您必須使用Control.Begin/Invoke()。如果沒有調試器,則不會得到異常,因爲只有在連接調試器時纔會默認啓用此線程檢查。這並不意味着在沒有調試器的情況下運行代碼是安全的,它會隨機導致繪圖問題或死鎖,儘管您可能必須等待一天或一週才能發生。

+0

嗨漢斯,我用InnerException編輯了這個問題。謝謝! – Dula 2011-03-29 18:49:44

+0

答覆已更新。 – 2011-03-29 18:55:58

+0

讓Hans很有意義,但是爲什麼_ffList.Add(ff);在線工作。該列表是由UI線程創建的,不是它。除非我不能只訪問不同線程的控件? – Dula 2011-03-29 19:16:01

0

正在拋出的異常是「管理調試助手」
只有當調試器被連接並且試圖警告你,你正在做的錯誤的工作大部分時間時纔會發生。
在這種情況下,你所做的錯在於從一個非創建它的線程訪問控制lstBox。 (Windows窗體不是線程安全的)

我不能很好地遵循你的問題,但我認爲你有一個方法在調用客戶端上的對象的服務器端對象。這意味着在客戶端上運行的代碼正在爲遠程處理基礎架構服務的線程池線程上運行,而不是您應用程序的主線程,因此出現錯誤。

關於這個錯誤的問題和Invoke方法(你將用它來修復它)已經被問過很多次了,這裏有一個Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on看一看,我不想爲你做所有的功課。:)

一個警告。如果您的應用程序線程仍在等待服務器響應,並且您嘗試使用Invoke,那麼您的應用程序可能會掛起。例如,你不能這樣做 客戶端應用程序調用服務器方法foo 服務器foo方法調用客戶端的方法吧 客戶端方法欄使用Invoke來調用客戶端的方法掛

進行的調用,現在正等待主線程上,正在等待呼叫Foo完成,正在等待呼叫完成,等待Invoke完成,正在等待主線程空閒,這意味着等待Foo的呼叫完成,等等...