C# Windows Service with multiple timers from file - c#

I have multiple "jobs" with timers in a file.
I want to use all of them but when i start the service i see that only the last timer in the configuration is working
How can i do have multiple timers created based on a List that can change over time (yes i can restart the service when i change the list but i don't want to write a timer foreach
Here is the code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using InserterService.Dao;
namespace InserterService
{
public partial class InserterService : ServiceBase
{
public InserterService()
{
InitializeComponent();
}
class CustomTimer : System.Timers.Timer
{
public Configurazione configurazione;
}
protected override void OnStart(string[] args)
{
//** CARICA CONFIGURAZIONI **//
// PER OGNI CONFIGURAZIONE DEFINISCO IL TIMER
List<Configurazione> Configurazioni = new List<Configurazione>();
Configurazioni = ModulReader.GetModulCopyDirectory();
int i = 0;
foreach (var item in Configurazioni )
{
i++;
string data = string.Format("CONFIGURAZIONE {0}",i.ToString());
string folder = #"C:\temp\OUT\";
// Filename
string fileName = "Test.txt";
// Fullpath. You can direct hardcode it if you like.
string fullPath = folder + fileName;
File.AppendAllText(fullPath, data);
var timer = new CustomTimer
{
Interval = Int32.Parse(item.TIMER.Trim()),
configurazione = item
};
timer.Elapsed += Lavorazione;
timer.Start();
}
}
public void Lavorazione(object sender, ElapsedEventArgs e)
{
Configurazione configurazione = ((CustomTimer)sender).configurazione;
string data = configurazione.DATA;
string folder = #"C:\temp\OUT\";
// Filename
string fileName = "Test.txt";
// Fullpath. You can direct hardcode it if you like.
string fullPath = folder + fileName;
File.AppendAllText(fullPath, data);
}
protected override void OnStop()
{
}
}
}

Related

Asp.NET MVC FileSystemWatcher does not work after close browser

I created file system watcher in my mvc application. But there is one problem: when client closes browser and leave application for a long time file system watcher stops working. File watcher monitores a ftp directory, everyday at roughly 23:58 or 00-00 data refreshes. Here is the code of file system watcher and Global.asax.cs:
MonitorConfig.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using KegokProj.Models;
using KegokProj.BLL;
using System.Web.Hosting;
namespace KegokProj.App_Start
{
public class MonitorConfig
{
public static void RegisterWatchers()
{
var fileWatcher = FileWatcher.ObserveFolderChanges(#"F:\ftp\data", "*.txt", TimeSpan.FromSeconds(1))
.Subscribe(fce =>
{
if (fce != null)
RecordEntry(fce.FileName);
});
}
private static void RecordEntry(string fileName)
{
BLogic bll = new BLogic();
bll.AddParamsByFileWatcher(fileName);
}
}
}
Global.asax.cs:
using FluentScheduler;
using KegokProj.App_Start;
using KegokProj.BLL;
using KegokProj.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;
namespace KegokProj
{
public class MvcApplication : HttpApplication, IHttpHandler, IRequiresSessionState
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
MonitorConfig.RegisterWatchers();
}
}
}
FileWatcher class:
using KegokProj.BLL;
using KegokProj.Controllers;
using KegokProj.DAL;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Web;
using System.Web.Hosting;
namespace KegokProj.Models
{
public class FileWatcher
{
public class FileChangedEvent
{
public string FullPath { get; private set; }
public string FileName { get; private set; }
public bool IsFileDeleted { get; private set; }
public bool IsFileChanged { get; private set; }
public FileChangedEvent(string path, string fileName, bool isFileDeleted = false, bool isFileChanged = false)
{
FullPath = path;
FileName = fileName;
IsFileDeleted = isFileDeleted;
IsFileChanged = isFileChanged;
}
}
public static IObservable<FileChangedEvent> ObserveFolderChanges(string path, string filter, TimeSpan throttle)
{
return Observable.Using(
() => new FileSystemWatcher(path, filter) { EnableRaisingEvents = true },
fileSystemWatcher => CreateSources(fileSystemWatcher)
.Merge()
.GroupBy(c => c.FullPath)
.SelectMany(fileEvents => fileEvents
.Throttle(throttle)
.Where(e => !e.IsFileChanged)));
}
private static IObservable<FileChangedEvent>[] CreateSources(FileSystemWatcher fileWatcher)
{
return new[]
{
Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs >(handler => fileWatcher.Created += handler, handler => fileWatcher.Created -= handler)
.Select(ev => new FileChangedEvent(ev.EventArgs.FullPath, ev.EventArgs.Name)),
Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs >(handler => fileWatcher.Deleted += handler, handler => fileWatcher.Deleted -= handler)
.Select(ev => new FileChangedEvent(ev.EventArgs.FullPath, ev.EventArgs.Name, true)),
Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs >(handler => fileWatcher.Changed += handler, handler => fileWatcher.Changed -= handler)
.Select(ev => new FileChangedEvent(ev.EventArgs.FullPath, ev.EventArgs.Name)),
//The rename source needs to send a delete event for the old file name.
//Observable.Create<FileChangedEvent>(nameChangedObserver =>
//{
// return Observable.FromEventPattern<RenamedEventHandler, RenamedEventArgs>(handler => fileWatcher.Renamed += handler, handler => fileWatcher.Renamed -= handler)
// .Subscribe(ev =>
// {
// nameChangedObserver.OnNext(new FileChangedEvent(ev.EventArgs.FullPath, ev.EventArgs.Name));
// nameChangedObserver.OnNext(new FileChangedEvent(ev.EventArgs.OldFullPath, ev.EventArgs.Name, true));
// });
//}),
Observable.FromEventPattern<ErrorEventHandler, ErrorEventArgs >(handler => fileWatcher.Error += handler, handler => fileWatcher.Error -= handler)
.SelectMany(ev => Observable.Throw<FileChangedEvent>(ev.EventArgs.GetException()))
};
}
}
}
You need to host your filesystem watcher in a Windows Server or in an IIS Always-on website. IIS will automatically close your application pool thread, or create new parallel ones if the load requires it.
IIS Application Pool recycling reference https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/recycling/

Writing form state to xml C#

My aim is to save the all form data via button click (as opposed to upon closing). To that end, I've used the example given in the following thread. Saving the form state then opening it back up in the same state
I've tried to adapt my code to the best of my ability, but nothing happens, and there are no errors shown. What am I doing wrong?
Here's the relevant parts of my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace WindowsFormsApplication1
{
public partial class frmPayroll : Form
{
SaveData sd = new SaveData();
public frmPayroll()
{
InitializeComponent();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
writeConfig();
}
private void writeConfig()
{
using (StreamWriter sw = new StreamWriter("config.xml"))
{
sd.Married = rdoMarr.Checked;
sd.PayPd = cbPayPd.Text;
sd.Allow = cbAllow.Text;
sd.Gross = txtGross.Text;
sd.Fit = txtFit.Text;
sd.Soc = txtSoc.Text;
sd.Med = txtMed.Text;
sd.NetPay = txtNet.Text;
sd.PayPd = cbPayPd.Text;
XmlSerializer ser = new XmlSerializer(typeof(SaveData));
ser.Serialize(sw, sd);
}
}
private void frmPayroll_Load(object sender, EventArgs e)
{
if (File.Exists("config.xml"))
{
loadConfig();
}
sd.Married = rdoMarr.Checked;
sd.PayPd = cbPayPd.Text;
sd.Allow = cbAllow.Text;
sd.Gross = txtGross.Text;
sd.Fit = txtFit.Text;
sd.Soc = txtSoc.Text;
sd.Med = txtMed.Text;
sd.NetPay = txtNet.Text;
}
private void loadConfig()
{
XmlSerializer ser = new XmlSerializer(typeof(SaveData));
using (FileStream fs = File.OpenRead("config.xml"))
{
sd = (SaveData)ser.Deserialize(fs);
}
}
}
public struct SaveData
{
public bool Married;
public string PayPd;
public string Allow;
public string Gross;
public string Fit;
public string Soc;
public string Med;
public string NetPay;
}
}
You are loading your object by deserializing.
But Where are you assigning the states back to your controls?
look at frmPayroll_Load function.
You are trying to assign the data back to the object again.
You have to assign data back to form controls.
Should be something like this (you may need to apply data conversions if required):
rdoMarr.Checked = sd.Married;
.
.
.
.
txtFit.Text = sd.Fit;
.
.
.
.

Exception Handling in a Windows Forms Application

I'm doing a program for serial communications. To centralize the process of access to serial, created a class.
I am having problem when an exception is lançanda within the class leaves the locked program.
example:
When trying aberir the serial port, can give error and the system is at that point to burst memory.
How should I handle errors?
Put try and catch?
Add another routine?
Error point:
portSerial.Open();
Program
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PortSerial.Lib;
namespace ProgramPortSerial
{
public partial class Form1 : Form {
public static LibPortaSerial portSerial = new LibPortSerial();
public Form1()
{
InitializeComponent();
portSerial.LineReceived += new LineReceivedEventHandler(sp1_LineReceived);
portSerial.Init(
ref cmbPortas,
ref cmbVelocidade,
ref cmbBitsDeDados,
ref cmbPariedade,
ref cmbBitsDeParada,
ref cmbControleDeFluxo);
}
void sp1_LineReceived(object sender, LineReceivedEventArgs Args)
{
// Tem que ser em uma nova thread para não travar
Invoke(new Action(() =>
{
memDadosRecebidos.Text += "\r\n" + Args.Resposta;
}));
}
private void btnAbrirPorta_Click(object sender, EventArgs e)
{
portSerial.Open();
}
}
}
Class PortSerial
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
namespace PortSerial.Lib
{
public class LibPortSerial : IDisposable
{
public SerialPort portSerial;
public LibPortSerial()
{
portSerial = new SerialPort();
}
public void Dispose()
{
if (portSerial != null)
portSerial.Dispose();
}
public void Open(
string port,
int veloc,
int bitsData,
string pariedade,
string bitsStop,
string control)
{
portSerial.PortName = port;
portSerial.BaudRate = veloc;
portSerial.DataBits = bitsData;
portSerial.Parity = SetPariedade(pariedade);
portSerial.StopBits = SetBitsStop(bitsStop);
portSerial.Handshake = Setcontrol(control);
portSerial.Open(); // ==> Erro this point
}
}
}
You should write it as:
public void Open(
string port,
int veloc,
int bitsData,
string pariedade,
string bitsStop,
string control)
{
portSerial.PortName = port;
portSerial.BaudRate = veloc;
portSerial.DataBits = bitsData;
portSerial.Parity = SetPariedade(pariedade);
portSerial.StopBits = SetBitsStop(bitsStop);
portSerial.Handshake = Setcontrol(control);
try
{
portSerial.Open(); // ==> Erro this point
}
catch(IOException exp)
{
return exp.Message;
}
}

C# speech recogntion engine recognizes everything wrong

I have been trying to make a personal assistant in my free time, and so far i have made him speak, but now i am trying to speak to him. Whenever i do however, he fails massively. When i say "Hello my name is Alexander" he recognizes "in the name is unresolved bush" or something else that is just not correct. am i doing something wrong or is the built in C# recognition engine just broken?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TTS_Test
{
class Jarvis
{
private static SpeechSynthesizer synthezier;
private static String name;
public Jarvis()
{
synthezier = new SpeechSynthesizer();
synthezier.SelectVoiceByHints(VoiceGender.Male, VoiceAge.Senior);
synthezier.Volume = 100;
synthezier.Rate = 0;
}
private bool isFirstTime()
{
if (File.Exists("config"))
{
return false;
}else{
return true;
}
}
private void firstTimeSetup()
{
say("Hello, My name is Jarvis. It seems that this is your first time here. Please take some time to configure the application.");
Config config = new Config();
config.ShowDialog();
say("Thank you! I should be up and running now.");
}
public void initiate()
{
if (isFirstTime())
{
firstTimeSetup();
}
setupUserData();
say("Hello " + name+". How may i help you today?");
recognize();
}
public void setupUserData()
{
StreamReader reader = new StreamReader("config");
name = reader.ReadLine();
reader.Close();
}
public void say(string output)
{
synthezier.Speak(output);
}
public void recognize()
{
SpeechRecognitionEngine sr = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-GB"));
sr.LoadGrammar(new DictationGrammar());
sr.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
sr.SetInputToDefaultAudioDevice();
RecognitionResult result = sr.Recognize();
MessageBox.Show(result.Text);
}
}
}
You should train your computer to better understand you by going to the Control Panel\All Control Panel Items\Speech Recognition

Does WqlEventQuery contain a constructor with 1 argument?

I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");

Categories

Resources