我們有一個服務器應用程序,通過TCP套接字與客戶端進行通信。運行幾周後,它會崩潰,並導致無法處理的NullReferenceException。我已經能夠用一個非常小的控制檯程序重現異常,但似乎在內部套接字線程池中存在未處理的異常。所以我不能用任何try/catch塊來處理它,因爲它不在我的控制之下。NullReferenceException,C#套接字BeginConnect中的錯誤?
有沒有人對此有任何意見?它是一個框架錯誤,或者我怎樣才能捕捉套接字線程池中的異常(所以我們的應用程序沒有崩潰)? 以下是經過幾次迭代(3-10)後生成異常的示例代碼。瞭解服務器處於脫機狀態很重要,因此套接字無法連接。它用於Visual Studio 2010和.Net框架4.0。
internal class Program
{
private static string host;
private static Socket socket;
private static void Main(string[] args)
{
Trace.Listeners.Add(new ConsoleTraceListener());
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
host = "127.0.0.1";
//aslo the problem is happening whe the host is other network ip address
//host = "192.168.0.1";
//when in other thread doesn not crash application
//Task.Factory.StartNew(() => StartConnecting());
//also crashing the application
//Task.Factory.StartNew(() => StartConnecting(), TaskCreationOptions.LongRunning);
//when it is regular thread the exception occurs
///*
var thread = new Thread(new ThreadStart(StartConnecting));
thread.Start();
//*/
//when it is blocking exception also occurs
//StartConnecting();
Console.WriteLine("Press any key to exit ...");
Console.ReadKey();
}
private static void StartConnecting()
{
try
{
int count = 0;
while (true)
{
try
{
// if i must switch to Socket.Connect(...)?
Trace.WriteLine(string.Format("Connect Try {0} begin", ++count));
var ar = socket.BeginConnect(host, 6500, new AsyncCallback(ConnectCallback), socket);
Trace.WriteLine(string.Format("Connect Try {0} end", count));
}
catch (Exception err)
{
Trace.WriteLine(string.Format("[BeginConnect] error {0}", err.ToString()));
}
System.Threading.Thread.Sleep(1000);
//will see the exception more quick
}
}
catch (Exception e)
{
Trace.WriteLine(string.Format("[StartConnecting] error {0}", e.ToString()));
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string msg = e.ExceptionObject.ToString();
Trace.WriteLine(string.Format("[CurrentDomain_UnhandledException] isTerminating={0} error {1}", e.IsTerminating, msg));
Trace.WriteLine("Exiting process");
//the other processing threads continue working
//without problems untill there is thread.sleep
//Thread.Sleep(10000);
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
Trace.WriteLine("[ConnectCallback] enter");
var socket = (Socket)ar.AsyncState;
socket.EndConnect(ar);
Trace.WriteLine("[ConnectCallback] exit");
}
catch (Exception e)
{
Trace.WriteLine(string.Format("[ConnectCallback] error {0}", e.ToString()));
}
}
}
應用程序啓動後,將發生不可避免的碰撞:
[CurrentDomain_UnhandledException] isTerminating=True error System.NullReferenceException: Object reference not set to an instance of an object.
at System.Net.Sockets.Socket.ConnectCallback()
at System.Net.Sockets.Socket.RegisteredWaitCallback(Object state, Boolean timedOut)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)
我面臨同樣的問題。我非常有信心這是一個框架中的錯誤。 ConnectCallback函數在這裏http://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket.cs,7be8fddc24c74b66,references沒有檢查'asyncResult'不爲空,這可能是一些競爭條件。既然你有再生案例,你應該提交連接。 http://connect.microsoft.com/ –
可能重複[什麼是NullReferenceException,我該如何解決它?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-我怎麼辦 - 修復它) – Rob
@rob - 當然不是。請仔細閱讀,這發生在.NET自己的代碼中(嘗試代碼)。 –