我們有一個C#應用程序,它連接到FTP服務器,下載一些文件,斷開連接並在一段時間後(由用戶通過UI選擇)重新連接並重復該過程。我們使用BackgroundWorker實現了這個功能,但我們注意到,在運行更長時間之後,程序停止記錄其操作,無論是在UI還是日誌文件中。 那時,沒有文件要下載,所以我們上傳了一些文件,它恢復了活動,就好像什麼都沒發生過一樣。線程停止工作
問題是,普通用戶無法知道該程序仍在工作,所以我們決定使用自己的線程來實現它。我們做了一個更簡單的程序,排除其他任何問題,並且這個程序只連接到FTP並斷開連接。它停止顯示消息,就像BackgroundWorker一樣(2小時後一次,22小時後一次,沒有任何我們可以找到的模式,並且在沒有其他任何事情的計算機上)。
DoFTPWork += new DoFTPWorkDelegate(WriteFTPMessage);
FTPWorkThread = new Thread(new ParameterizedThreadStart(Process));
//seData is the FTP login info
FTPWorkThread.Start(seData);
和FTP方法是:
private void Process(object seData1)
{
seData = (SEData)seData1;
while (!stopped)
{
try
{
ftp = null;
ftp = new FTP_Client();
if (ftp.IsConnected)
{
logMessages += DateTime.Now + "\t" + "info" + "\t" + "Ftp disconnected from " + seData.host + "\r\n";
ftp.Disconnect();
}
ftp.Connect(seData.host, 21);
ftp.Authenticate(seData.userName, seData.password);
logMessages += DateTime.Now + "\t" + "info" + "\t" + "Ftp connected to " + seData.host + "\r\n";
error = false;
logMessages += DateTime.Now + "\t" + "info" + "\t" + "Trying to reconnect in 5 seconds\r\n";
System.Threading.Thread.Sleep(5000);
SlaveEventArgs ev = new SlaveEventArgs();
ev.Message = logMessages;
txtLog.Invoke(DoFTPWork, ev);
System.Threading.Thread.Sleep(200);
logMessages = "";
}
catch (Exception ex)
{
logMessages = "";
if (ftp.IsConnected)
{
ftp.Disconnect();
}
ftp.Dispose();
logMessages += DateTime.Now + "\t" + "ERR" + "\t" + ex.Message + "\r\n";
logMessages += DateTime.Now + "\t" + "info" + "\t" + "Trying to reconnect in 5 seconds\r\n";
SlaveEventArgs ev = new SlaveEventArgs();
ev.Message = logMessages;
txtLog.Invoke(DoFTPWork, ev);
System.Threading.Thread.Sleep(5 * 1000);
error = true;
}
}
}
WriteFTPMessage在TextBox顯示消息並在原始程序中寫爲.txt文件。
+1爲資源泄漏部分。如果有很多活動連接,可能很容易達到(可能很小)限制並導致掛起。 – 2009-01-12 07:38:03
我們進行了一次重組,此外,我們每隔100行就清除UI中的日誌文本框,並且客戶沒有再報告任何凍結。 – Rox 2009-11-20 07:12:05