I have a windows service that fetches data from WCF and it is working fine. I want to trigger the service after 5 minutes. If there are 10,000 records that have to be inserted - I want to avoid inserting duplicates. How can I increase the timer if the original insert isn't complete.
Below is my code:
protected override void OnStart(string[] args)
{
// System.Diagnostics.Debugger.Launch();
try
{
m_mainTimer = new System.Timers.Timer();
m_mainTimer.Interval = 10*60000; // every ten min
m_mainTimer.Elapsed += new System.Timers.ElapsedEventHandler(main_function);
m_mainTimer.AutoReset = false; // makes it fire only once
m_mainTimer.Enabled = true;
}
catch (Exception e)
{
}
}
public void main_function(object sender,ElapsedEventArgs e)
{
while (true)
{
try
{
FetchRecord fn = new FetchRecord();
fn.loadNotificationsInEcasDBFromSAP_CTRL();
}
catch (Exception ex)
{
}
finally
{
if (null != m_mainTimer)
{
m_mainTimer.Start(); // re - enable the timer
}
}
}
}
protected override void OnStop()
{
try
{
// Service stopped. Also stop the timer.
m_mainTimer.Enabled = false;
m_mainTimer = null;
}
catch (Exception ex)
{
}
}
Related
I have a C# console application. I want to execute a function every minute, for up to 1 hour. The function returns a bool value. If the function returns true, the timer should stop else it should keep executing every minute, for up to 1 hour.
Below is my code I have written so far.
static void Main(string[] args)
{
var timer = new System.Timers.Timer(60000);
timer.Elapsed += new
System.Timers.ElapsedEventHandler(CheckEndProcessStatus);
//if timer timed out, stop executing the function
}
private void CheckEndProcessStatus(object source, ElapsedEventArgs args)
{
try
{
if (CheckFunction())
{
//stop timer
}
}
catch(Exception ex)
{
throw;
}
}
private bool CheckFunction()
{
bool check = false;
try
{
//some logic to set 'check' to true or false
}
catch (Exception ex)
{
throw;
}
return check;
}
I think I need some guidance on this to implement this. Please let me know if I can provide more details on this.
Just call timer.stop() to stop the timer. It internally calls timer.Enabled = false
Use another timer to stop the first timer after one hour.
private static Timer timer;
private static Timer oneHourTimer;
static void Main(string[] args)
{
oneHourTimer = new System.Timers.Timer(3600 * 1000);
timer = new System.Timers.Timer(60 * 1000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(CheckEndProcessStatus);
oneHourTimer.Elapsed += oneHourTimer_Elapsed;
oneHourTimer.Start();
timer.Start();
}
static void oneHourTimer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Stop();
//maybe stop one hour timer as well here
oneHourTimer.Stop();
}
private static void CheckEndProcessStatus(object source, ElapsedEventArgs args)
{
try
{
if (CheckFunction())
{
//stop timer
timer.Stop();
}
}
catch (Exception ex)
{
throw;
}
}
private static bool CheckFunction()
{
bool check = false;
try
{
//some logic to set 'check' to true or false
}
catch (Exception ex)
{
throw;
}
return check;
}
I have a method that send some SMS to our customers that look like below:
public void ProccessSmsQueue()
{
SmsDbContext context = new SmsDbContext();
ISmsProvider provider = new ZenviaProvider();
SmsManager manager = new SmsManager(context, provider);
try
{
manager.ProcessQueue();
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.Message, EventLogEntryType.Error);
}
finally
{
context.Dispose();
}
}
protected override void OnStart(string[] args)
{
Task.Factory.StartNew(DoWork).ContinueWith( ??? )
}
So, I have some issues:
I donĀ“t know how long it takes for the method run;
The method can throw exceptions, that I want to write on EventLog
I want to run this method in loop, every 10 min, but only after last execution finish.
How I can achieve this? I thought about using ContinueWith(), but I still have questions on how to build the entire logic.
You should have an async method that accepts a CancellationToken so it knows when to stop, calls ProccessSmsQueue in a try-catch block and uses Task.Delay to asynchronously wait until the next time it needs to run:
public async Task DoWorkAsync(CancellationToken token)
{
while (true)
{
try
{
ProccessSmsQueue();
}
catch (Exception e)
{
// Handle exception
}
await Task.Delay(TimeSpan.FromMinutes(10), token);
}
}
You can call this method when your application starts and Task.Wait the returned task before existing so you know it completes and has no exceptions:
private Task _proccessSmsQueueTask;
private CancellationTokenSource _cancellationTokenSource;
protected override void OnStart(string[] args)
{
_cancellationTokenSource = new CancellationTokenSource();
_proccessSmsQueueTask = Task.Run(() => DoWorkAsync(_cancellationTokenSource.Token));
}
protected override void OnStop()
{
_cancellationTokenSource.Cancel();
try
{
_proccessSmsQueueTask.Wait();
}
catch (Exception e)
{
// handle exeption
}
}
Sample Worker Class that I have used in Windows Services. It supports stopping in a 'clean' way by using a lock.
You just have to add your code in DoWork, set your timer in the StartTimerAndWork method (in milliseconds), and use this class in your service.
public class TempWorker
{
private System.Timers.Timer _timer = new System.Timers.Timer();
private Thread _thread = null;
private object _workerStopRequestedLock = new object();
private bool _workerStopRequested = false;
private object _loopInProgressLock = new object();
private bool _loopInProgress = false;
bool LoopInProgress
{
get
{
bool rez = true;
lock (_loopInProgressLock)
rez = _loopInProgress;
return rez;
}
set
{
lock (_loopInProgressLock)
_loopInProgress = value;
}
}
#region constructors
public TempWorker()
{
}
#endregion
#region public methods
public void StartWorker()
{
lock (_workerStopRequestedLock)
{
this._workerStopRequested = false;
}
_thread = new Thread(new ThreadStart(StartTimerAndWork));
_thread.Start();
}
public void StopWorker()
{
if (this._thread == null)
return;
lock (_workerStopRequestedLock)
this._workerStopRequested = true;
int iter = 0;
while (LoopInProgress)
{
Thread.Sleep(100);
iter++;
if (iter == 60)
{
_thread.Abort();
}
}
//if (!_thread.Join(60000))
// _thread.Abort();
}
#endregion
#region private methods
private void StartTimerAndWork()
{
this._timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
this._timer.Interval = 10000;//milliseconds
this._timer.Enabled = true;
this._timer.Start();
}
#endregion
#region event handlers
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (!LoopInProgress)
{
lock (_workerStopRequestedLock)
{
if (this._workerStopRequested)
{
this._timer.Stop();
return;
}
}
DoWork();
}
}
private void DoWork()
{
try
{
this.LoopInProgress = true;
//DO WORK HERE
}
catch (Exception ex)
{
//LOG EXCEPTION HERE
}
finally
{
this.LoopInProgress = false;
}
}
#endregion
}
I've written a small WCF WebService (.svc) which I want to call from other applications. It's working fine so far.
In another application I've got a Windows Form. When this is shown, it will call BackgroundWorker1 to get a list of objects from the WebService and show it to the user on it's completed1-method. So far, so good.
Now, after the user selects one object and clicks "ok", then BackgroundWorker2 will call the WebService again to gather more information. But here, within the doWork2-method exactly after the WebService-call, the whole application breaks without any exceptions or errors. It just closes directly after the WebService is called.
This is very weird, because as I have a look at the WebServices log files, it seems to work normal and still logs the successful operation AFTER the other application is closed. So the WebService cannot be the problem, I think.
Another weird thing: If I call the WebService the second time on the GUI thread (and not with BackgroundWorker2), it just works. It blocks the UI, but it works.
So, why is my application just "broken" after the second call without any notification?
Any ideas are very much welcomed.
Thanks in advance.
Greets
Here's some simplified code. The application closes in "bgwGetSingleCar_DoWork":
public partial class MyForm : Form
{
private Controller _ctrl { get; set; }
private Config _config { get; set; }
private List<Cars> _cars { get; set; }
public bool Result { get; private set; }
public MyForm(Controller ctrl, Config config)
{
this._ctrl = ctrl;
this._config = config;
this.Result = false;
InitializeComponent();
}
private void MyForm_Load(object sender, EventArgs e)
{
try
{
this.bgwGetAllOffers.RunWorkerAsync(new WorkerInfo()
{
WorkerType = WorkerType.Type1,
IdLocal = this._config.IdLocal,
IdExternal = this._config.IdExternal,
});
}
catch (Exception ex)
{
// ...
}
}
private void FillList(List<Cars> list)
{
// ...
}
private void btnOk_Click(object sender, EventArgs e)
{
CarListItem v = (CarListItem)this.lstBoxCars.SelectedValue;
this._config.IdExternal = v.IdExternal;
try
{
this.bgwGetSingleCar.RunWorkerAsync(new WorkerInfo()
{
WorkerType = WorkerType.Type2,
IdLocal = this._config.IdLocal,
IdExternal = this._config.IdExternal,
});
}
catch (Exception ex)
{
// ...
}
}
private void bgwGetAllCars_DoWork(object sender, DoWorkEventArgs e)
{
try
{
WorkerInfo info = (WorkerInfo)e.Argument;
Client client = new Client();
GetCarsResult result = client.GetAllCars(new GetAllCarsRequest()
{
IdLocal = info.IdLocal,
IdExternal = info.IdExternal
});
if (!result.Success)
{
// ...
}
if (result.Cars != null)
{
this._cars = result.Cars.ToList();
}
}
catch (Exception ex)
{
/// ...
}
}
private void bgwGetAllCars_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.FillList(this._cars);
}
private void bgwGetSingleCar_DoWork(object sender, DoWorkEventArgs e)
{
try
{
WorkerInfo info = (WorkerInfo)e.Argument;
Client client = new Client();
// Application closes after this line, but WebService log still shows activity
GetCarsResult result = client.GetSingleCar(new GetSingleCarRequest()
{
IdLocal = info.IdLocal,
IdExternal = info.IdExternal
});
if (result.Success)
{
this.Result = true;
}
}
catch (Exception ex)
{
/// ...
}
}
private void bgwGetSingleOffer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
}
public class CarListItem : Car
{
public override string ToString()
{
return ((DateTime)this.LastUpdate).ToString("dd.MM.yyyy - HH:mm");
}
}
I just found my "design break".
It was the button's "DialogResult" which caused the application to close too soon. But strange that the debugger didn't step ahead...
I want to know how to stop and restart a thread.
I create N amount of threads, depending on conditions returned from a database. These are long running processes which should never stop but should I get a critical error within the thread I want to completely kill the thread and start it up like new.
The code which I use currently to start the threads:
foreach (MobileAccounts MobileAccount in ReceiverAccounts)
{
Receiver rec = new Receiver();
ThreadStart starterParameters = delegate { rec.StartListener(MobileAccount); };
Thread FeedbackThread = new Thread(starterParameters);
FeedbackThread.Name = MobileAccount.FriendlyName;
FeedbackThread.Start();
Thread.Sleep(1000);
}
You can write your own listener and manage its thread within it.
something like:
public class AccountListener
{
private Thread _worker = null;
private MobileAccount _mobileAccount;
public AccountListener(MobileAccount mobileAccount)
{
_mobileAccount = mobileAccount;
}
protected void Listen()
{
try
{
DoWork();
}
catch (Exception exc)
{
}
}
protected virtual void DoWork()
{
Console.WriteLine(_mobileAccount);
}
public void Start()
{
if (_worker == null)
{
_worker = new Thread(Listen);
}
_worker.Start();
}
public void Stop()
{
try
{
_worker.Abort();
}
catch (Exception)
{
//thrad abort exception
}
finally
{
_worker = null;
}
}
}
i'm trying to create an application which connects to internet and consume web services for every of it's operation.As far as i'm concerned i'll like to useasync method which i'm using already to get a collection of Contacts.I've realized that when i'm doing the same for groups (meaning getting groups async) i'm having errors in the calls , but when using normal call there ins't.So i did some research online and find that a lot of people has the same problem.
Some of them are asked to use WCF (for which i don't know jack).I'll like to know if there is another way to overcome this. if not can somebody point me to reliable resource online and help me get through it? thanks for reading and helping
here is my code:
public partial class main : Window
{
//...
private static vmcSession session;
private MyService service = new MyService();
private contactInfo[] loadedcontact;
//....
public main()
{
InitializeComponent();
//service.addContactCompleted +=new addContactCompletedEventHandler(addContactCompleted);
service.getContactsCompleted += new getContactsCompletedEventHandler(getContactsCompleted);
service.getGroupsCompleted += new getGroupsCompletedEventHandler(getGroupsCompleted);
fillContents();
}
private void getGroupsCompleted(object sender, getGroupsCompletedEventArgs e)
{
try
{
groupListBox.ItemsSource = e.Result;
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.Message);
}
}
private void getContactsCompleted(object sender, getContactsCompletedEventArgs e)
{
try
{
loadedcontact = e.Result;
contactListBox.ItemsSource = loadedcontact;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void addContactCompleted(object sender, addContactCompletedEventArgs e)
{
throw new NotImplementedException();
}
public void fillContents()
{
displayUserInformation();
loadContacts();
service.getGroupsAsync(session.key, null);
//groupListBox.ItemsSource = service.getGroups(session.key, null);
cmbSenderIds.ItemsSource = service.getSenderIds(session.key, null);
if (cmbSenderIds.Items.Count > 0)
{
cmbSenderIds.SelectedIndex = 0;
}
loadGrid();
}
public void loadContacts()
{
service.getContactsAsync(session.key, null);
}
public void displayUserInformation()
{
lblName.Content = session.user.firstName;
lblEmail.Content = session.user.email;
lblCreditValue.Content = Decimal.Ceiling(session.user.balance).ToString();
}
public void loadGrid()
{
try
{
hitoryGrid.ItemsSource = service.viewMessages(session.key, null).ToList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
solve it.there are 2 methods with async calls, one with additional parameter Unique ID.each of the call needed ID, so i pass new GUID to it and that's it.thanks for trying helping me