私は、私をまっすぐに見つめている何かを見逃しているに違いないと思います。
ファイルが別のプロセス エラーによって開かれています。
これが私のコードです
ロガー.cs:
public class Logger
{
/// <summary>
/// Log File Path
/// </summary>
public string LogFilePath { get; set; }
/// <summary>
/// Writer
/// </summary>
public StreamWriter Writer { get; set; }
// This is a reference to the form so that we can use its threadsafe Invoke to calls methods on non thread safe UI controls.
private readonly Form _form;
/// <summary>
///Parameterless Constructor
/// </summary>
public Logger()
{
}
/// <summary>
/// Call this constructor with the reference to the form.
/// </summary>
/// <param name="form"></param>
public Logger(Form form)
{
_form = form;
}
public void CreateLogFile()
{
try
{
String filePath = string.Format("{0:yyyy-MM-dd}", DateTime.Now);
// This is the text file created with time stamps
var folderName = ConfigurationManager.AppSettings["FolderToCreate"];
String txtFile = string.Format("Log{0:yyyy-MM-dd hh-mm-ss-tt}", DateTime.Now) + ".txt";
// Given in config to read the path
var localhostizedLetter = ConfigurationManager.AppSettings["localhostDriveLetter"] + "//";
//Create directory
string pathString = Path.Combine(localhostizedLetter, folderName);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
// Create a folder inside directory
// If folder exists dont create it
pathString = Path.Combine(pathString, filePath);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
// create a file inside d://DataSummarisationDatetime.now//datetimewithtimestamp.txt
// if exists please dont create it.
pathString = Path.Combine(pathString, txtFile);
if (!Directory.Exists(pathString))
{
// here my file is created and opened.
// so I m doing a try catch to make sure if file is opened we are closing it so that nother process can use it
File.Create(pathString).Dispose();
var fileInfo = new FileInfo(pathString);
IsFileLocked(fileInfo);
}
LogFilePath = pathString;
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// To check if File is opened by another process.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
/// <summary>
/// Log message using textwriter
/// </summary>
/// <param name="logMessage"></param>
/// <param name="w"></param>
public static void Log(string logMessage, TextWriter w)
{
w.Write("\r\n" + DateTime.Now + " " + logMessage);
w.Flush();
}
/// <summary>
/// Call this function to log your message
/// </summary>
/// <param name="textLog"></param>
public void Log(string textLog)
{
StreamWriter sw = null;
if (!File.Exists(LogFilePath))
{
try
{
sw = File.CreateText(LogFilePath);
}
catch (Exception exception)
{
throw exception;
}
finally
{
sw.Dispose();
}
}
try
{
using (StreamWriter w = File.AppendText(LogFilePath))
{
Log(textLog, w);
w.Close();
}
}
catch (Exception exception)
{
throw exception;
}
}
/// <summary>
/// Call this function when it says file is already been using somewhere
/// </summary>
public void Dispose(string path)
{
File.Create(path).Close(); //Will close underlying stream
}
}
_logger を使用した私のクラス:
private void TimerRetailerFeedTick(object sender, EventArgs e)
{
//Are we already processing one?
if (_doingRetailerFeed)
{
//Yes,dont start another
return;
}
//Say we are doing one
_doingRetailerFeed = true;
_logger.CreateLogFile();
var scrapeStat = new ScrapeStatRepository();
var stringBuilder = new StringBuilder();
var scrapeRepository = new ScrapeRepository();
var manufacturers = ConfigurationManager.AppSettings["Manufacturers"];
var countries = ConfigurationManager.AppSettings["Countries"];
if (_maxThreads == 0)
{
_maxThreads = 1;
}
ThreadPool.SetMinThreads(_maxThreads, _maxThreads);
ThreadPool.SetMaxThreads(_maxThreads, _maxThreads);
var dueFeeds = scrapeRepository.GetAllDueRetailerfeedForApiManufacturersAndCountriesList(manufacturers,
"RetailerFeeds",
countries);
// 5. Get when the feed is last run i.e closeofplay(Datetime now) date minus the feed current updatedate got from databse and if it is
//greater than 24 hours (Interval) then add it to the list of feeds that are due to run.
// var countDoing = dueScrapes.Count();
if (dueFeeds.Any())
{
_logger.Log(" Processing Retailer feeds on timer tick");
_logger.Log(" Total due feeds to run : " + dueFeeds.Count());
timerRetailerFeed.Interval = 15 * 60 * 1000;
foreach (var feed in dueFeeds)
{
object scrapeObject = feed;
var scrapeStatRow = scrapeStat.GetScrapeStatByScrapeId(feed.Id);
int totalProductUrls = scrapeStatRow.TotalProductUrls;
int urlsFound = scrapeStatRow.UrlsFound;
int urlsNotFound = scrapeStatRow.UrlsNotFound;
_logger.Log(" ");
_logger.Log(" Feed details :" + feed);
stringBuilder.Append(" && ");
stringBuilder.Append("Retailer " + feed.Retailer.Description + " Has " + "Total Product Urls : " +
totalProductUrls + " Total Url's found : " + urlsFound +
" Total Urls not found : " + urlsNotFound);
// stringBuilder.Append(" , ");
// _logger.Log(" Proceesing Retailer : " + feed.Retailer.Description);
ThreadPool.QueueUserWorkItem(o => UpdateRetailer(scrapeObject, true));
// _logger.Log(" Status : finished");
}
//Say we have finished
_logger.Log(" Finished doing Retailers on Timer Basis ");
var filePath = _logger.LogFilePath;
var systemName = Dns.GetHostName();
_keepItDry.SendRetailerFeedNotification("Ended RetailerFeeds Interface on Server " + systemName,
stringBuilder.ToString(), filePath);
_keepItDry.AddTolistBox(
DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() +
": Ended RetailerFeeds interface ", _listBoxLog);
//_logger.Dispose(filePath);
}
_doingRetailerFeed = false;
}
スレッドプールから UpdateRetailer を呼び出しています
private void UpdateRetailer(object scrapeObject, object value)
{
_logger.Log(" Writing : " + downloadFileName);
}
プロセスが別のプロセスによって使用されているという例外が発生するので、これを試しました:
Invoke(new System.Action(() =>
{
_logger.Log(" Writing : " + downloadFileName);
}));
しかし、私はまだ同じエラーが発生しています。
どんなアドバイスも役に立ちます。