Time Thread is stopping running - c#

I'm not finding the bug, but this thread is stopping after some time of execution, it returns a message "Thread was being aborted."
Sometimes it takes a hour, in another takes four, I can't find a patern, in some cases it never stops, but I can't find anything relate to it
using System.Threading;
namespace NewMVC.infraestructure
{
public class Thread_iFood
{
private static bool inicializado = false;
static Thread_iFood instance = null;
static readonly object padlock = new object();
private const int timer = 30000;
static Timer thProcessaRet = new Timer(PollingIfood, null, Timeout.Infinite, Timeout.Infinite);
private Thread_iFood()
{
}
public static void Reiniciar()
{
inicializado = false;
instance = null;
}
public static Thread_iFood GetInstance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Thread_iFood();
}
}
}
return instance;
}
}
internal static async void PollingIfood(Object obj)
{
try
{
thProcessaRet.Change(Timeout.Infinite, Timeout.Infinite);
MetodosAuxiliares.BuscaPedidosIFood();
}
catch (Exception e)
{
LogErros.GravaLog(e, "Thread_iFood/PollingIfood");
//here is where is stopping (Thread was being aborted.)
}
finally
{
thProcessaRet.Change(timer, Timeout.Infinite);
}
}
public void Inicializa()
{
if (!inicializado)
{
inicializado = true;
thProcessaRet.Change(timer, timer);
}
}
}
}

Related

How can I stop a method being called more than once in 5 seconds?

I have this method:
public static async Task OpenPageAsync(string route)
{
await Shell.Current.GoToAsync(route, true);
}
If the method is called more than once in 5 seconds I would like the second call to be ignored. Has anyone come across a way to deal with this need?
Note that if it helps I do have access to create properities at the App level like this etc.
public partial class App : Application
{
public static int LastTapTime;
public static int TapTime;
In our project, we have created a 'MaxFrequencyUpdater' for exactly that cause.
Only difference: if within 5 seconds a new call comes in, it is delayed and executed after the 5 seconds interval.
namespace Utils
{
public class MaxFrequencyUpdater
{
private readonly WinformsExceptionHandler _exceptionHandler;
private readonly string _name;
private readonly int _millis;
private MethodInvoker _currentMethod;
private DateTime _lastExecuted = DateTime.MinValue;
private readonly object _updaterLockObject = new object();
public MaxFrequencyUpdater(string name, int maxFrequencyInMillis, WinformsExceptionHandler exceptionHandler)
{
_name = name;
_exceptionHandler = exceptionHandler;
_millis = maxFrequencyInMillis;
}
public void Update(MethodInvoker method)
{
lock (_updaterLockObject)
{
_currentMethod = method;
}
Task.Run(HandleWork);
}
private void HandleWork()
{
lock (_updaterLockObject)
{
// No longer bother, someone else handled it already
if (_currentMethod == null) return;
var now = DateTime.Now;
var delay = (int)(_millis - now.Subtract(_lastExecuted).TotalMilliseconds);
// Post-pone if too soon
if (delay > 0)
{
Task.Delay(delay).ContinueWith(HandleWork);
}
else
{
try
{
_currentMethod.Invoke();
}
catch (Exception e)
{
_exceptionHandler.HandleException(e);
}
_lastExecuted = now;
_currentMethod = null;
}
}
}
}
}
usage:
_maxFrequencyUpdater.Update(() =>
{
doSomething();
});

Best Practice EventWaitHandle.Dispose() in Multi-Threaded Environment

I was creating a small logger. For that purpose I have a class (LogFile) which publishes the Log(ILogCsvLine csvLine) method. This method adds the line to log to a queue (linesToLog) and sets a trigger, that has been registered to the ThreadPool with Logging(..) as method that should be executed on a different thread whenever there is a trigger and pending processor time. The Logging(..) method is writing the lines to log to a given file.
Now I ran into the problem, that the Dispose() method has been called, while the queue wasn't empty, resulting in a call to the Logging(..) method, while trigger or fileAccessLock were already disposed. As a solution I've build some checks around those EventWaitHandles and was wondering whether there is a better readable and more elegant way of doing this.
internal sealed class LogFile : ILogFile
{
private readonly EventWaitHandle fileAccessLock = new AutoResetEvent(true);
private readonly IFilesLoader filesLoader;
private readonly Queue<ILogCsvLine> linesToLog = new Queue<ILogCsvLine>();
private readonly IFile logFile;
private readonly object myLock = new object();
private RegisteredWaitHandle registeredWait;
private readonly EventWaitHandle trigger = new AutoResetEvent(false);
private IDirectory directory = null;
private bool disposeFileAccessLock = false;
private bool disposeTrigger = false;
private bool isDisposed = false;
private bool isDisposing = false;
private bool isLogging = false;
private bool isSettingTrigger = false;
public event EventHandler<FilesException> LoggingFailed;
public LogFile(IFile logFile, IFilesLoader filesLoader)
{
this.filesLoader = filesLoader;
this.logFile = logFile;
Setup();
}
private void Setup()
{
directory = logFile.ParentDirectory;
EnforceFileExists();
registeredWait = ThreadPool.RegisterWaitForSingleObject(trigger, Logging, null, -1, false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~LogFile()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!isDisposed)
{
try
{
lock (myLock)
isDisposing = true;
registeredWait?.Unregister(trigger);
if (disposing)
{
if (isSettingTrigger)
disposeTrigger = true;
else
trigger?.Dispose();
if (isLogging)
disposeFileAccessLock = true;
else
fileAccessLock?.Dispose();
}
}
finally
{
isDisposed = true;
lock (myLock)
isDisposing = false;
}
}
}
public IFile File => logFile;
public void Log(ILogCsvLine csvLine)
{
lock (myLock)
{
if (isDisposing || isDisposed)
return;
linesToLog.Enqueue(csvLine);
isSettingTrigger = true;
}
trigger.Set();
lock (myLock)
{
isSettingTrigger = false;
if (disposeTrigger)
trigger?.Dispose();
}
}
private void Logging(object data, bool timedOut)
{
ILogCsvLine line = null;
lock (myLock)
{
if (linesToLog.Count == 0)
return;
if (isDisposing || isDisposed)
return;
line = linesToLog.Dequeue();
isLogging = true;
}
fileAccessLock.WaitOne();
FilesException occurredException = null;
IStreamWriter sw = null;
try
{
EnforceFileExists();
sw = logFile.AppendText();
do
{
sw.WriteLine(line.ToCsvString());
lock (myLock)
{
if (linesToLog.Count > 0)
line = linesToLog.Dequeue();
else
line = null;
}
} while (line != null);
}
catch (Exception e)
{
if (e is ThreadAbortException)
throw;
string message = string.Format("Error writing to {0}. {1}", logFile.Path, e.Message);
occurredException = new FilesException(message, e);
}
finally
{
if (sw != null)
{
sw.Flush();
sw.Close();
sw = null;
}
}
fileSizeManager?.Check();
fileAccessLock.Set();
lock (myLock)
{
if (disposeFileAccessLock)
fileAccessLock?.Dispose();
isLogging = false;
}
if (occurredException != null)
LoggingFailed?.Invoke(this, occurredException);
}
private void EnforceFileExists()
{
if (!directory.Exists)
directory.Create();
if (!logFile.Exists)
{
var fileAccess = filesLoader.GetFileAccess();
fileAccess.Create(logFile.Path, FileSystemRights.Read | FileSystemRights.Write);
}
}
}

Call methods from the main thread - UnityEngine C# [duplicate]

This question already has answers here:
Use Unity API from another Thread or call a function in the main Thread
(5 answers)
Closed 6 years ago.
I'm having trouble with a UnityEngine version. (Can't upgrade, game is not mine)
The server RANDOMLY crashes when a specific UnityEngine method is used in a timer/thread (It was fixed in a version, I read It)
It happens totally random, I get a crash log, that starts from the timer/thread and ends at a UnityEngine method. (This never happens when I use It in the main thread)
My question is that Is It possible somehow to call the method from the main thread if the current thread != with the main thread?
Any help is appreciated
This Loom class is able to call the specific method from the Main thread, this is how you do It:
public class Loom : MonoBehaviour
{
public static int maxThreads = 10;
static int numThreads;
private static Loom _current;
private int _count;
public static Loom Current
{
get
{
Initialize();
return _current;
}
}
public void Awake()
{
_current = this;
initialized = true;
}
static bool initialized;
static void Initialize()
{
if (!initialized)
{
if (!Application.isPlaying)
return;
initialized = true;
var g = new GameObject("Loom");
_current = g.AddComponent<Loom>();
}
}
private List<Action> _actions = new List<Action>();
public struct DelayedQueueItem
{
public float time;
public Action action;
}
private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
public static void QueueOnMainThread(Action action)
{
QueueOnMainThread(action, 0f);
}
public static void QueueOnMainThread(Action action, float time)
{
if (time != 0)
{
lock (Current._delayed)
{
Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
}
}
else
{
lock (Current._actions)
{
Current._actions.Add(action);
}
}
}
public static Thread RunAsync(Action a)
{
Initialize();
while (numThreads >= maxThreads)
{
Thread.Sleep(1);
}
Interlocked.Increment(ref numThreads);
ThreadPool.QueueUserWorkItem(RunAction, a);
return null;
}
private static void RunAction(object action)
{
try
{
((Action)action)();
}
catch
{
}
finally
{
Interlocked.Decrement(ref numThreads);
}
}
public void OnDisable()
{
if (_current == this)
{
_current = null;
}
}
// Use this for initialization
public void Start()
{
}
List<Action> _currentActions = new List<Action>();
// Update is called once per frame
public void Update()
{
lock (_actions)
{
_currentActions.Clear();
_currentActions.AddRange(_actions);
_actions.Clear();
}
foreach (var a in _currentActions)
{
a();
}
lock (_delayed)
{
_currentDelayed.Clear();
_currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
foreach (var item in _currentDelayed)
_delayed.Remove(item);
}
foreach (var delayed in _currentDelayed)
{
delayed.action();
}
}
}
//Usage
public void Call()
{
if (Thread.CurrentThread.ManagedThreadId != TestClass.MainThread.ManagedThreadId)
{
Loom.QueueOnMainThread(() => {
Call();
});
return;
}
Console.WriteLine("Hello");
}

Best way to do a task looping in Windows Service

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
}

C# read write lock on list

Desription:
I am adding some data to list every second. After every 10 seconds, the data is saved to the database and then I clear the list. If I stop the timer, I am saving the data remaining in the list and then clearing the list and then stopping the timer.
In the above code, Let's say when I stop the timer after 11 seconds, The Class1s list should have only 1 data, but I see there are 11 datas. Can you guys tell what I am doing wrong here? Maybe my use of lock is incorrect or my code is totally incorrect
public class Class1Singleton
{
private static Class1Singleton Class1Singleton;
private static List<Class1> Class1s;
private static Timer saveClass1Timer;
private static readonly object lock1 = new object();
private Class1Singleton()
{
}
public static Class1Singleton getInstance()
{
if (Class1Singleton == null) {
try
{
Class1Singleton = new Class1Singleton();
}
catch (Exception e){}
}
return Class1Singleton;
}
public void StartTimer()
{
if (saveClass1Timer == null)
{
saveClass1Timer = new Timer(10000);
//saveClass1Timer.Interval = 10000;
saveClass1Timer.Elapsed += new ElapsedEventHandler(SaveClass1);
saveClass1Timer.Enabled = true;
}
}
public void SaveClass1(object sender, ElapsedEventArgs e)
{
try {
lock (lock1)
{
new Class1Repository().InsertAllClass1(Class1s);
ClearWorkoutList();
}
}
catch (Exception ex){}
}
public void InsertClass1(List<Class1> Class1)
{
if (Class1s == null)
{
Class1s = new List<Class1>(Class1);
}
else
{
lock (lock1)
{
Class1s.AddRange(Class1);
}
}
}
public void ClearWorkoutList()
{
if (Class1s != null)
{
Class1s.Clear();
}
}
public void StopTimer()
{
if (Class1s != null && Class1s.Count > 0)
{
lock (lock1)
{
new Class1Repository().InsertAllClass1(Class1s);
ClearWorkoutList();
}
}
if (saveClass1Timer != null && saveClass1Timer.Enabled == true)
{
saveClass1Timer.Stop();
}
}
}
I've made a few changes to your code (see comments):
public class Class1Singleton
{
// This is the way Jon Skeet recommends implementing a singleton in C#
// See http://csharpindepth.com/Articles/General/Singleton.aspx
static readonly Class1Singleton instance = new Class1Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Class1Singleton() { }
// There's only one instance of Class1Singleton so there's
// no advantage in making the members static
private List<Class1> Class1s;
private Timer saveClass1Timer;
private readonly object lock1 = new object();
Class1Singleton()
{
}
public static Class1Singleton Instance
{
get { return instance; }
}
public void StartTimer()
{
// If you're using this class in a multi-thread environment,
// all methods that access the list or timer should be locked
lock (lock1)
{
if (saveClass1Timer == null)
{
saveClass1Timer = new Timer(10000);
//saveClass1Timer.Interval = 10000;
saveClass1Timer.Elapsed += new ElapsedEventHandler(SaveClass1);
saveClass1Timer.Enabled = true;
}
}
}
// SaveClass1 doesn't need to be public
private void SaveClass1(object sender, ElapsedEventArgs e)
{
lock (lock1)
{
SaveWorkoutList();
ClearWorkoutList();
}
}
private void SaveWorkoutList()
{
//new Class1Repository().InsertAllClass1(Class1s);
}
public void InsertClass1(List<Class1> Class1)
{
lock (lock1)
{
if (Class1s == null)
Class1s = new List<Class1>(Class1);
else
Class1s.AddRange(Class1);
}
}
private void ClearWorkoutList()
{
if (Class1s != null)
{
Class1s.Clear();
}
}
public void StopTimer()
{
lock (lock1)
{
if (Class1s != null && Class1s.Count > 0)
{
SaveWorkoutList();
ClearWorkoutList();
}
if (saveClass1Timer != null && saveClass1Timer.Enabled == true)
{
saveClass1Timer.Stop();
}
}
}
}

Categories

Resources