How to use named Mutex - c#

I'm trying to use Mutex to handle different process/application to write on same file.
This is my code
ILogTest logTest = new LogTest(new FileLog());
logTest.PerformanceTest();
public class ILogTest
{
public void PerformanceTest()
{
for (int i = 0; i < this.numberOfIterations; i++)
{
try
{
Thread threadC = Thread.CurrentThread;
threadC = new Thread(ThreadProc);
threadC.Name = i.ToString();
threadC.Start();
threadC.Suspend();
threadC.IsBackground = true;
}
catch (Exception)
{
throw new Exception("errore");
}
}
}
private void ThreadProc()
{
try
{
log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString());
}
catch (Exception)
{
throw new Exception("errore");
}
}
}
FileLog is an implementation of ILogTest.
Write method :
public void Write(string message)
{
try
{
rwl.WaitOne();
try
{
string tID = Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.CurrentCulture);
sw.WriteLine(sev.ToString() + "\t" + DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss", CultureInfo.CurrentCulture) + "\t\t" + System.Reflection.Assembly.GetCallingAssembly().GetName().Name + "\t" + Process.GetCurrentProcess().Id.ToString(CultureInfo.CurrentCulture) + "\t" + tID + " \t " + message);
sw.WriteLine("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
}
catch (Exception ex)
{
throw new ArgumentException("Cannot write to file " + ex.Message);
}
finally
{
rwl.ReleaseMutex();
}
}
catch (ApplicationException)
{
}
}
FileLog main :
public FileLog()
{
try
{
rwl.WaitOne();
string filePath = Path.GetTempPath() + "Test.txt";
if (!File.Exists(filePath))
{
swa = new FileStream(filePath, FileMode.Append, FileAccess.Write);
sw = new StreamWriter(swa);
}
}
catch (Exception ex)
{
throw new ArgumentException("Cannot open or create file " + ex.Message);
}
try
{
if (sw == null)
{
swa = new FileStream(filePath, FileMode.Append, FileAccess.Write);
sw = new StreamWriter(swa);
}
sw.AutoFlush = true;
}
catch (Exception ex)
{
throw new ArgumentException("Cannot write to file " + ex.Message);
}
}
Trying simulate it, it doesn't write anything to file, only create it..
I don't know why.
Could anyone help me? thanks

The FileLog constructor calls rwl.WaitOne() which acquires the mutex (I'm assuming rwl is a Mutex object), but never calls rwl.ReleaseMutex().
Thus, every thread that calls Write() blocks on its call to rwl.WaitOne() because the mutex is still owned by another thread.
You will need to release the Mutex in the FileLog constructor so that other threads can acquire it.
Also, you have a call to threadC.Suspend(); in PerformanceTest; unless there is code that resumes the threads, they will never finish running.

Related

Why can't I catch this XML exception?

Context
I've written a class to handle settings for my ASP.NET MVC app. However after testing how it handles a malformed/ missing XML file the exception it seems to throw is uncatchable and it repeats endlessly without catching or moving on with execution.
I've disabled the V.S. Debug Dialog popup in the past but again it seems repeat the same segment of code. I do not have a loop anywhere else that calls this property and there is default behavior if the property doesn't return a valid value.
Breakpoints beyond the failing function are not reached, however the breakpoint on or before the XML exception are repeatedly reached...
P.S. there is a lot of failed testing code left over to get a workaround working.
Screenshot:
Screenshot:
EDIT: I must clarify I have tried alternate XML parsing tools, any XMLException here is not caught.
Code ['Setting container' Property]:
private static Settings _singletonSettings;
public static Settings SettingsContainer
{
get
{
if (_singletonSettings == null)
{
_singletonSettings = new Settings();
_singletonSettings .LoadSettings();
}
return _singletonSettings;
}
private set
{
_singletonSettings = value;
}
}
Code ['LoadSettings function']:
public void LoadSettings()
{
string filePath = "Config/Settings.txt";
if (!Directory.Exists(Path.GetDirectoryName(filePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
}
if (File.Exists(filePath))
{
try
{
SettingsContainer = LoadViaDataContractSerialization<Settings>(filePath); // Desperately trying to catch the exception.
}
catch (Exception ex)
{
Log.GlobalLog.WriteError("LoadViaDataContractSerialization() error:\n" + ex.Message + "\nStackTrace: \n" + ex.StackTrace);
}
}
else
{
File.Create(filePath);
}
if (SettingsContainer == null)
{
SettingsContainer = new Settings();
}
}
Code ['LoadViaDataContractSerialization']:
public static T LoadViaDataContractSerialization<T>(string filepath)
{
try
{
T serializableObject;
using (var fileStream = new FileStream(filepath, FileMode.Open))
{
try
{
using (var reader = XmlDictionaryReader.CreateTextReader(fileStream, new XmlDictionaryReaderQuotas())) //All execution stops here with the
{
var serializer = new DataContractSerializer(typeof(T));
serializableObject = (T)serializer.ReadObject(reader, true);
reader.Close();
}
}
catch (XmlException ex)
{
Log.GlobalLog.WriteError("LoadViaDataContractSerialization() XML Fail: Message: " + ex.Message + "\n StackTrace: " + ex.StackTrace);
return default(T);
}
fileStream.Close();
}
return serializableObject;
}
catch (Exception ex)
{
Log.GlobalLog.WriteError("LoadViaDataContractSerialization() Fail: Message: " + ex.Message + "\n StackTrace: " + ex.StackTrace);
return default(T);
}
}
Looks like the issue lay with a lack of understanding in 'return default(T)'.
I'm not sure why it was repeating but by removing the try catch blocks that returned 'default(T)' and responding to the exception 'return new settings()' it allowed the properties value to not be null and function as intended.
Code LoadViaDataContractSerialization:
public static T LoadViaDataContractSerialization<T>(string filepath)
{
T serializableObject;
using (var fileStream = new FileStream(filepath, FileMode.Open))
{
using (var reader = XmlDictionaryReader.CreateTextReader(fileStream, new XmlDictionaryReaderQuotas()))
{
var serializer = new DataContractSerializer(typeof(T));
serializableObject = (T)serializer.ReadObject(reader, true);
reader.Close();
}
fileStream.Close();
}
return serializableObject;
}
Code LoadSettings:
public void LoadSettings()
{
string filePath = "Config/Settings.txt";
if (!Directory.Exists(Path.GetDirectoryName(filePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
}
if (File.Exists(filePath))
{
try
{
SettingsContainer = LoadViaDataContractSerialization<Settings>(filePath);
}
catch (Exception ex) //only exception needed
{
Log.GlobalLog.WriteError("LoadViaDataContractSerialization() error:\n" + ex.Message + "\nStackTrace: \n" + ex.StackTrace);
SettingsContainer = new Settings();//<---this was the fix
}
}
else
{
File.Create(filePath);
}
if(SettingsContainer == null)
{
SettingsContainer = new Settings();
}
}
Thank you to 'Generic Snake' for pointing me at the right place.

C# WUApiLib: Failing to Install Updates with 0x80240024 Even Though Updates are Found

I have followed instructions found on this site, which was found when I researched Stack Overflow and found this question. However, I can't seem to figure out why my code is hitting the catch block. I have a break at the IInstallationResult line, which the code hits but then goes to the catch, stating 0x80240024 (There are no updates), even though there are certainly updates available and I list them in the text box.
What am I missing here?
using System;
using System.Windows.Forms;
using WUApiLib;
namespace TEST.DetectWindowsUpdate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void GetUpdates(bool downloadUpdates, bool installUpdates)
{
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
UpdateCollection updatesToInstall = new UpdateCollection();
UpdateDownloader downloader = uSession.CreateUpdateDownloader();
IUpdateInstaller installer = uSession.CreateUpdateInstaller();
uSearcher.Online = true;
try
{
ISearchResult sResult = uSearcher.Search("IsInstalled=0 And Type='Software'");
lblUpdateCount.Text = sResult.Updates.Count.ToString();
foreach (IUpdate update in sResult.Updates)
{
txtUpdatesList.AppendText("Title: " + update.Title + Environment.NewLine);
txtUpdatesList.AppendText("IsInstalled: " + update.IsInstalled.ToString() + Environment.NewLine);
txtUpdatesList.AppendText("Downloaded: " + update.IsDownloaded.ToString() + Environment.NewLine);
txtUpdatesList.AppendText("IsMandatory: " + update.IsMandatory.ToString() + Environment.NewLine);
txtUpdatesList.AppendText(Environment.NewLine);
if (downloadUpdates)
{
if (update.IsDownloaded == false)
{
do
{
downloader.Updates.Add(update);
downloader.Download();
}
while (update.IsDownloaded == false);
if (update.IsDownloaded == true)
{
updatesToInstall.Add(update);
}
}
else
{
updatesToInstall.Add(update);
}
}
if (installUpdates)
{
installer.Updates = updatesToInstall;
IInstallationResult installationRes = installer.Install();
for (int i = 0; i < updatesToInstall.Count; i++)
{
txtUpdatesList.AppendText("Installing " + updatesToInstall[i].Title + "...");
if (installationRes.GetUpdateResult(i).HResult == 0)
{
txtUpdatesList.AppendText("INSTALL SUCCESS FOR " + updatesToInstall[i].Title);
}
else
{
txtUpdatesList.AppendText("INSTALL FAIL FOR " + updatesToInstall[i].Title);
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message + ": " + ex.HelpLink);
}
}
private void btnGetUpdates_Click(object sender, EventArgs e)
{
base.OnLoad(e);
txtUpdatesList.Clear();
GetUpdates(false, false);
}
private void btnInstallUpdates_Click(object sender, EventArgs e)
{
base.OnLoad(e);
txtUpdatesList.Clear();
GetUpdates(true, true );
}
}
}
Turns out it was an issue with privileges. I ran as administrator and it functioned appropriately.

Form without movement when filling in DataGridView

I use a DataGridView as a console for an application, I need to fill it out every second, I use the following code for this:
public class dgView
{
public static DataGridView DataConsole;
public static void addLinha(int tipo_acao, string acao, string extra, int tipo_extra)
{
// INSERE LINHA NO CONSOLE
try
{
if (DataConsole == null) return;
var idLinha = DataConsole.Rows.Add();
using (var linha = DataConsole.Rows[idLinha])
{
//await Task.Delay(300);
if (tipo_acao == 0)
{
linha.DefaultCellStyle.ForeColor = Color.Teal;
linha.Cells[3].Style.ForeColor = Color.Gray;
}
else if (tipo_acao == 1)
{
linha.DefaultCellStyle.ForeColor = Color.Yellow;
linha.Cells[3].Style.ForeColor = Color.Orange;
}
else
{
linha.DefaultCellStyle.ForeColor = Color.Red;
linha.Cells[3].Style.ForeColor = Color.Magenta;
}
linha.Cells["dg_data"].Value = DateTime.Now;
linha.Cells["dg_mapa"].Value = "" + Config.Mapa + "";
linha.Cells["dg_acao"].Value = "" + Config.rm.GetString("" + acao + "") + "";
if (tipo_extra == 0)
{
linha.Cells["dg_extra"].Value = "" + extra + "";
}
else
{
linha.Cells["dg_extra"].Value = "" + Config.rm.GetString(extra) + "";
}
DataConsole.CurrentCell = DataConsole.Rows[idLinha].Cells[0];
//DataConsole.Refresh();
}
}
catch (Exception ex)
{
throw;
}
}
}
However, the form freezes and I can't move it to any part of the screen, would there be any way to solve this? Remembering that the DataGridView is not, and cannot be populated through the DataSource property, but by a constant verification in the system.
Example:
public static void Abrir(string metodoChamador)
{
try
{
Abrir:
dgView.addLinha(2, "config_Abrir", "config_Validando", 1);
Thread.Sleep(5000);
Atalho:
string AtalhoExiste = "" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk";
if (!File.Exists(AtalhoExiste))
{
dgView.addLinha(2, "config_FaltaIcone", "", 0);
Thread.Sleep(5000);
goto Atalho;
}
else
{
ProcessStartInfo info = new ProcessStartInfo(#"" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk");
Process whatever = Process.Start(info);
whatever.Dispose();
Thread.Sleep(5000);
IntPtr WinHandle = Win32.FindWindow(null, Config.Atalho);
if (WinHandle == (IntPtr)0)
{
goto Abrir;
}
}
}
catch (Exception ex)
{
throw;
}
}
It's hard to tell if you have other potential problems in the code. Basically anywhere you have Thread.Sleep(), your GUI is going to freeze.
Here's a possible refactoring of your Abrir() method, using async\await and Task.Delay() as suggested by JQSOFT:
public async static void Abrir(string metodoChamador)
{
try
{
IntPtr WinHandle = IntPtr.Zero;
do
{
dgView.addLinha(2, "config_Abrir", "config_Validando", 1);
await Task.Delay(5000);
string AtalhoExiste = "" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk";
while (!File.Exists(AtalhoExiste))
{
dgView.addLinha(2, "config_FaltaIcone", "", 0);
await Task.Delay(5000);
}
ProcessStartInfo info = new ProcessStartInfo(#"" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk");
Process whatever = Process.Start(info);
whatever.Dispose();
await Task.Delay(5000);
WinHandle = Win32.FindWindow(null, Config.Atalho);
}
while (WinHandle.Equals(IntPtr.Zero));
}
catch (Exception ex)
{
throw;
}
}
If you have Thread.Sleep() in other locations, they would need to be refactored.
If you have any other infinite loops using goto, those may need to be refactored as well.

Csvhelper write with windows service

I am using csvhelper with windows service which runs non stop. I want to create a new csv log file and put the header values only once until the file size grown to 1000 kb and then create another new file so the file size grow too big. At the moment csv file is created once when windows service starts but it repeats header values every time it writes into it.
Do we have some config properties in csv helper to flag size file?
Please have a look at the code and suggest if it can be done efficiently in .net 4.0.
Windows Service code
public partial class Service1 : ServiceBase
{
private Thread executeThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
Thread.Sleep(30000);
executeThread = new Thread(new ThreadStart(Execute));
executeThread.Start();
}
catch (Exception e)
{
Library.LogData("Error : " + DateTime.UtcNow + " " + e.Message);
OnStop();
}
}
protected override void OnStop()
{
try
{
Library.LogData("Stopped: " + DateTime.UtcNow);
executeThread.Abort();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
public void Execute()
{
try
{
Library.LogData("Started");
while (true)
{
Library.LogData("Logging Execute" + DateTime.UtcNow);
Thread.Sleep(5000);
}
}
catch (Exception e)
{
Library.LogData("Error : " + DateTime.UtcNow + " " + e.Message);
OnStop();
}
Library.LogData("Out of Execute" + DateTime.UtcNow);
}
}
Logging code called by windows service
public static class Library
{
public static void LogData(string Message)
{
StreamWriter sw = null;
GetData getData = new GetData();
var dataClasslist = new List<DataClass>
{
new DataClass {}
};
try
{
dataClasslist = getData.ReadData();
using (sw = new StreamWriter("E:\\DataLogs\\LogFile.csv", true))
using (var csv = new CsvWriter(sw))
{
csv.Configuration.RegisterClassMap<DataClassMap>();
csv.WriteHeader<DataClass>();
csv.Configuration.TrimHeaders = true;
csv.Configuration.HasHeaderRecord = false;
csv.WriteRecords(dataClasslist);
sw.Flush();
sw.Close();
}
}
catch (Exception e)
{
var err = new StreamWriter("E:\\DataLogs\\Errors", true);
err.WriteLine(DateTime.Now.ToString() + ": " + e.Message.ToString());
err.Flush();
err.Close();
}
}
}
Main windows service
public partial class Service1 : ServiceBase
{
private Thread executeThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
Thread.Sleep(10000);
executeThread = new Thread(new ThreadStart(Execute));
executeThread.Start();
}
catch (Exception e)
{
var err = new StreamWriter("E:\\DataLogs\\Errors", true);
err.WriteLine(DateTime.Now.ToString() + " OnStart: " + e.Message.ToString());
err.Flush();
err.Close();
OnStop();
}
}
protected override void OnStop()
{
try
{
executeThread.Abort();
}
catch (Exception e)
{
var err = new StreamWriter("E:\\DataLogs\\Errors", true);
err.WriteLine(DateTime.Now.ToString() + "OnStop exception: " + e.Message.ToString());
err.Flush();
err.Close();
}
}
public void Execute()
{
try
{
StreamWriter sw = null;
string FileNameAndPath = null;
FileNameAndPath = "E:\\DataLogs\\LogFile" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".csv";
using (sw = new StreamWriter(FileNameAndPath, true))
{
sw.WriteLine("TimeStamp " + "," + "col1" + "," + "col2" + "," + "col3"
+ "," + "col4" + "," + "col5" + "," + "col6" + ","
+ "col8" + "," + "col9" + "," + "col7" + "," + "col10");
sw.Flush();
sw.Close();
}
while (true)
{
Library.LogData(FileNameAndPath);
Thread.Sleep(5000);
}
}
catch (Exception e)
{
var err = new StreamWriter("E:\\DataLogs\\Errors", true);
err.WriteLine(DateTime.Now.ToString() + " Execute: " + e.Message.ToString());
err.Flush();
err.Close();
OnStop();
}
}
public void TestInConsole(string[] args)
{
Console.WriteLine("Starting.....");
this.OnStart(args);
}
So OnExecute will be called as soon as file hits 100kb and new file will be created with headers written in it only once.
public static class Library
{
public static void LogData(string FileNameAndPath)
{
StreamWriter sw = null;
GetData getData = new GetData();
var dataClasslist = new List<DataClass>
{
new DataClass {}
};
try
{
//System.Diagnostics.Debugger.Break();
dataClasslist = getData.ReadData();
//Create a file seperately
using (sw = new StreamWriter(FileNameAndPath, true))
using (var csv = new CsvWriter(sw))
{
csv.Configuration.RegisterClassMap<DataClassMap>();
//csv.WriteHeader<DataClass>();
csv.Configuration.TrimHeaders = true;
csv.Configuration.HasHeaderRecord = false;
csv.WriteRecords(dataClasslist);
sw.Flush();
sw.Close();
}
var FileSize = new FileInfo(FileNameAndPath);
//for each 1000 kb
if (FileSize.Length >= 1e+6)
{
//go back to the start to create a new file and column headers
Service1 serive1 = new Service1();
serive1.Execute();
}
}
catch (Exception e)
{
var err = new StreamWriter("E:\\DataLogs\\Errors", true);
err.WriteLine(DateTime.Now.ToString() + " LogData: " + e.Message.ToString());
err.Flush();
err.Close();
}
}
}
Im open for suggests, please let me know if you can thing of a better way to to do this.

Service Logging not working

I am trying to add some logging functionality to a service, however I want it to create a new log, copy the old log into the new one and delete the original.
Sudo for ClearLog: if log1 full create log2, delete contents of log1
Please see code below, currently the ClearLog function is not doing what I want.
Can anyone see what I'm doing wrong?
public static void WriteLog(string txt)
{
string fp = _AppPath + #"\Logging";
try
{
File.AppendAllText(fp + #"\Log1.txt", txt);
}
catch (IOException iex)
{
Debug.Print("Error writing log" + iex.ToString());
}
}
private static void ClearLog()
{
string fp = _AppPath + #"\Logging";
try
{
if (!File.Exists(fp + #"\Log1.txt"))
{
WriteErrorLog("");
}
else
{
File.AppendAllText(fp + #"\Log1.txt", fp + #"\Log2.txt");
File.Delete(fp + #"\Log1.txt");
WriteLog("");
}
}
catch (Exception ex)
{
WriteLog("Clear log failed " + ex.ToString());
}
}
Try creating a public static field of the file path, as you're opening the same file twice it seems.
IE: public static string logfp = _AppPath + #"\Logging";
Then rename everything in those two functions logfp.
Improved example (can use paths in both or declared throughout)
private static void ClearLog()
{
string logfp = _AppPath + #"\Logging";
try
{
if (File.Exists(logfp + #"\Log2.txt"))
{
File.Delete(logfp + #"\Log2.txt");
if (File.Exists(logfp + #"\Log1.txt"))
{
File.Copy(logfp + #"\Log1.txt", logfp + #"\Log2.txt");
File.Delete(logfp + #"\Log1.txt");
}
else
{
File.AppendAllText(logfp + #"\Log1.txt", "New Log created: " + DateTime.Now.ToString());//showing you when it was created
}
}
else
{
File.Copy(logfp + #"\Log1.txt", logfp + #"\Log2.txt");
File.Delete(logfp + #"\Log1.txt");
}
}
catch (Exception ex)
{
WriteErrorLog("Clear log failed " + ex.ToString());
}
}

Categories