我構建了一個.NET Mono應用程序,該應用程序每分鐘都會將文本文件上載到服務器。這個應用程序確實需要全天候運行,我正在使用它將.rss提要中的數據傳輸到我們的圖文電視服務器,以便在電視上傳輸。 在我看來,避免崩潰應用程序的最好方法是使用上傳代碼的嘗試,以避免意外的錯誤。Try/Catch沒有捕捉到WebException
它總是運行正常約2天,之後它突然崩潰。我正在尋找原因已經幾個星期,但無法找到它。
我得到的錯誤是:
未處理的異常信息:System.Net.WebException:在System.Net.FtpWebRequest 0:在 System.Net.FtpWebRequest.CheckIfAborted()[0x00000]請求中止.set_Sate(RequestState值) [0x00000]中:0在 System.Net.FtpWebRequest.ProcessRequest(RequestState值)[0x00000] 中:在System.Threading.Thread.StartUnsafe() [0x00000]中:
你的PLOAD代碼線程內運行是:
private static readonly ILog log = LogManager.GetLogger(typeof(PheTextConnector));
static String ftp_path = ConfigurationManager.AppSettings["txtServerFTPPath"];
static String ip = ConfigurationManager.AppSettings["txtServerIP"];
static String username = ConfigurationManager.AppSettings["txtServerUsername"];
static String password = ConfigurationManager.AppSettings["txtServerPassword"];
public void UploadToTextServer(String filename, String uploadfolder)
{
try
{
UploadFile(ip, ftp_path, filename, username, password, uploadfolder);
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
public void UploadFile(string FTPAddress, string directory, string filename, string username, string password, string uploadfolder)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + FTPAddress + "/" + directory + "/" + Path.GetFileName(filename));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true;
FileStream fs = File.OpenRead(uploadfolder + "/" + filename);
int buffLength = 4096;
byte[] buffer = new byte[buffLength];
Stream strm = request.GetRequestStream();
int bytesRead = fs.Read(buffer, 0, buffer.Length);
while (true)
{
if (bytesRead == 0)
{
strm.Close();
fs.Close();
break;
}
else
{
strm.Write(buffer, 0, bytesRead);
bytesRead = fs.Read(buffer, 0, buffLength);
}
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
}
類調用上傳方法的代碼是:
using System;
using System.IO;
using System.Threading;
using log4net;
using System.Text.RegularExpressions;
using System.Configuration;
public class PhecapConnectionMain
{
private static readonly ILog log = LogManager.GetLogger(typeof(PhecapConnectionMain));
private Object thisLock = new Object();
private int waitTimeBetweenTxtUpdates = Int32.Parse(ConfigurationManager.AppSettings["txtServerTimeBetweenUpdates"]);
private String transferDirectory = ConfigurationManager.AppSettings["transferDirectoryName"];
public PhecapConnectionMain()
{
try
{
log.Debug("Start Phecap Connection");
CreateDirectoryIfNotExists(transferDirectory);
FileSystemWatcher _watcher = new FileSystemWatcher();
_watcher.Path = transferDirectory+"/";
_watcher.NotifyFilter = System.IO.NotifyFilters.DirectoryName;
_watcher.NotifyFilter = _watcher.NotifyFilter | System.IO.NotifyFilters.FileName;
_watcher.NotifyFilter = _watcher.NotifyFilter | System.IO.NotifyFilters.Attributes;
_watcher.EnableRaisingEvents = true;
_watcher.IncludeSubdirectories = true;
_watcher.Created += new FileSystemEventHandler(eventRaised);
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
/// <summary>
/// Triggered when an event is raised from the folder activity monitoring.
/// </summary>
/// <param name="sender"></param>
/// <param name="e">containing all data send from the event that got executed.</param>
private void eventRaised (object sender, System.IO.FileSystemEventArgs e)
{
String changedFileName = e.Name;
changedFileName = Regex.Replace (changedFileName, @"//", @"//");
changedFileName = String.Format(@"{0}",changedFileName);
switch(e.ChangeType)
{
case WatcherChangeTypes.Created:
if(changedFileName.Contains("update.sem"))
{
Thread thread = new Thread(NewFolderCreatedThread);
thread.Start(e);
}
break;
default:
break;
}
}
/// <summary>
/// Creates a directory if not exists.
/// </summary>
/// <param name='folderName'>
/// Folder name.
/// </param>
private void CreateDirectoryIfNotExists(String folderName)
{
if(Directory.Exists(folderName) == false)
{
Directory.CreateDirectory(folderName);
}
}
/// <summary>
/// News the folder created thread.
/// </summary>
/// <param name='parameterObject'>
/// Parameter object.
/// </param>/
public void NewFolderCreatedThread(object parameterObject)
{
// Lock object, one thread at a time may upload files
lock(thisLock)
{
try
{
System.IO.FileSystemEventArgs fileInfo = (System.IO.FileSystemEventArgs) parameterObject;
String[] splitted = fileInfo.Name.Split('/');
String directory = transferDirectory+"/"+splitted[splitted.Length-2]+"/";
string [] fileEntries = Directory.GetFiles(directory);
PheTextConnector pheTextConnector = new PheTextConnector();
int percentage = 0;
double counter = 1;
double lengt = fileEntries.Length;
foreach(string fName in fileEntries)
{
String[] tempSplitted = fName.Split('/');
String fileName = tempSplitted[tempSplitted.Length-1];
if(!fileName.Equals("update.sem"))
{
pheTextConnector.UploadToTextServer(fileName, directory);
}
double percent = (counter/lengt) * 100.0;
percentage = (int) percent;
ConsoleFunctions.RenderConsoleProgress(percentage, '\u2590', ConsoleColor.Yellow, "Uploading file " + fileName);
counter++;
}
pheTextConnector.UploadToTextServer("update.sem", directory);
Directory.Delete(directory, true);
log.Debug("Files are uploaded to server, wait " + waitTimeBetweenTxtUpdates + " milliseconds for releasing lock");
Thread.Sleep(waitTimeBetweenTxtUpdates);
log.Debug("Waiting complete... release lock and allow new updates to be uploaded to the server");
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
}
}
- 編輯:
我提高了UploadMethod使用的語句。並且通過將FTPWebRequest的超時值設置爲100 ms,找到了重現此錯誤的方法。 而不是由try catch捕獲的超時錯誤,應用程序完全崩潰。
using System;
using System.IO;
using System.Net;
using System.Configuration;
using log4net;
public class PheTextConnector
{
private static readonly ILog log = LogManager.GetLogger(typeof(PheTextConnector));
static String ftp_path = ConfigurationManager.AppSettings["txtServerFTPPath"];
static String ip = ConfigurationManager.AppSettings["txtServerIP"];
static String username = ConfigurationManager.AppSettings["txtServerUsername"];
static String password = ConfigurationManager.AppSettings["txtServerPassword"];
public void UploadToTextServer(String filename, String uploadfolder)
{
try
{
UploadFile(ip, ftp_path, filename, username, password, uploadfolder);
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
public void UploadFile(string FTPAddress, string directory, string filename, string username, string password, string uploadfolder)
{
try
{
FtpWebRequest request = (FtpWebRequest) WebRequest.Create("ftp://" + FTPAddress + "/" + directory + "/" + Path.GetFileName(filename));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true;
request.Timeout = 100;
byte[] buffer = new byte[4096];
using (FileStream fs = File.OpenRead(uploadfolder + "/" + filename))
{
using(Stream stream = request.GetRequestStream())
{
int bytesRead = fs.Read(buffer, 0, buffer.Length);
while (true)
{
if (bytesRead == 0)
{
stream.Close();
break;
}
else
{
stream.Write(buffer, 0, bytesRead);
bytesRead = fs.Read(buffer, 0, 4096);
}
}
}
}
using(FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
response.Close();
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch(Exception ex)
{
log.Error(ex.ToString());
}
}
}
System.Net.WebException: Request timed out
at System.Net.FtpWebRequest.EndGetRequestStream (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.GetRequestStream() [0x00000] in <filename unknown>:0
at PheTextConnector.UploadFile (System.String FTPAddress, System.String directory,
System.String filename, System.String username, System.String password, System.String
uploadfolder) [0x00094] in /svn/WOSTeletekst/WOSTxT/PheCapConnector
/PheTextConnector.cs:47
System.Net.WebException: Request aborted
at System.Net.FtpWebRequest.CheckIfAborted() [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.set_State (RequestState value) [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.UploadData() [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessMethod() [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessRequest() [0x00000] in <filename unknown>:0
Mb你的'log'類沒有初始化?你在'catch {}'塊中得到異常?嘗試調試它,你會看到你在哪裏得到異常。 – Maris 2013-02-20 09:45:39
我沒有插入整個類,* edit *,還插入了其餘的代碼。 – 2013-02-20 09:47:34
如何調試,在哪個字符串中出現錯誤? – Maris 2013-02-20 09:49:07