I am trying to use a System.Threading.Timer to perform a task every five seconds in a Http Module and the timer just randomly stops firing:
using Bookbyte.IpFilter.Manager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace Bookbyte.IpFilter
{
public class IpFilterModule : ApplicationStartModuleBase
{
private static object lockObject = new object();
private static Timer timer;
private static IpFilterManager filterManager;
private static IEnumerable<string> blacklist;
private static IEnumerable<string> whitelist;
public override void OnInit(HttpApplication context)
{
context.BeginRequest += (object sender, EventArgs e) =>
{
var app = sender as HttpApplication;
if (app != null)
{
var ipAddress = app.Request.UserHostAddress;
if (!whitelist.Any(x => x == ipAddress))
{
if (blacklist.Any(x => x == ipAddress))
{
app.Context.Response.StatusCode = 404;
app.Context.Response.SuppressContent = true;
app.Context.Response.End();
return;
}
}
}
};
base.OnInit(context);
}
public override void OnStart(HttpApplication context)
{
filterManager = new IpFilterManager();
blacklist = new List<string>();
whitelist = new List<string>();
timer = new Timer(new TimerCallback((object sender) =>
{
lock (lockObject)
{
blacklist = filterManager.GetBlacklist();
whitelist = filterManager.GetWhitelist();
}
}), null, 0, 5000);
base.OnStart(context);
}
public override void Dispose()
{
timer.Dispose();
base.Dispose();
}
}
}
And the ApplicationStartModuleBase:
using System.Web;
namespace Bookbyte.IpFilter
{
public abstract class ApplicationStartModuleBase : IHttpModule
{
private static volatile bool applicationStarted = false;
private static object applicationStartLock = new object();
public void Init(HttpApplication context)
{
if (!applicationStarted)
{
lock (applicationStartLock)
{
if (!applicationStarted)
{
this.OnStart(context);
applicationStarted = true;
}
}
}
this.OnInit(context);
}
public virtual void OnInit(HttpApplication context)
{
}
public virtual void OnStart(HttpApplication context)
{
}
public virtual void Dispose()
{
}
}
}
So I figured out the problem. The timer was being disposed in the module when the run time would call Dispose on the module.
public override void Dispose()
{
timer.Dispose();
base.Dispose();
}
Removing the call to timer.Dispose() fixed my issues.
Related
I have a WPF application in which lots of event initiate tasks. Here's how I am doing it. But I am not happy about how it looks now
var task = UpdatePersonModelAsync();
taskCollection.Add(task);
RaisePropertyChanged(nameof(IsUpdateInProgress));
await task;
taskCollection.Remove(task);
RaisePropertyChanged(nameof(IsUpdateInProgress));
The property which shows/hides spinner
public bool IsUpdateInProgress => taskCollection.Count > 0;
I was going through the Progress<T> it seems like a call back.
When all the incoming tasks are completed a small spinner will be hidden.
You probably should use await Task.WhenAll(taskCollection.ToArray()); for waiting all the tasks you need to wait. After that, put the code for hiding the spinner below the await statement.
I tried using a CustomTaskScheduler. I got it from https://www.infoworld.com/article/3063560/application-development/building-your-own-task-scheduler-in-c.html
http://www.codeguru.com/csharp/article.php/c18931/Understanding-the-NET-Task-Parallel-Library-TaskScheduler.htm
As tasks are created from various calls, I use the CustomTaskScheduler in Task.Factory.StartNew.
On debugging, I can get hits on QueueTask but Execute isn't getting called. What am I missing?
public sealed class CustomTaskScheduler : TaskScheduler, IDisposable
{
public delegate void TaskStartedHandler(Task sender);
public delegate void AllTasksCompletedHandler(IEnumerable<Task> sender);
public event TaskStartedHandler TaskStarted;
public event AllTasksCompletedHandler AllTasksCompleted;
private BlockingCollection<Task> tasksCollection = new BlockingCollection<Task>();
private readonly Thread mainThread = null;
public CustomTaskScheduler()
{
mainThread = new Thread(new ThreadStart(Execute));
if (!mainThread.IsAlive)
{
mainThread.Start();
}
}
private void Execute()
{
foreach (var task in tasksCollection.GetConsumingEnumerable())
{
var isStarted = TryExecuteTask(task);
if (isStarted && TaskStarted != null)
{
TaskStarted(task);
}
}
if(tasksCollection.GetConsumingEnumerable().All(m => m.IsCompleted))
{
AllTasksCompleted?.Invoke(tasksCollection.GetConsumingEnumerable());
}
}
protected override IEnumerable<Task> GetScheduledTasks()
{
return tasksCollection.ToArray();
}
protected override void QueueTask(Task task)
{
if (task != null)
{
tasksCollection.Add(task);
}
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
tasksCollection.CompleteAdding();
tasksCollection.Dispose();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
The code is not yet complete. It would be great if someone can point to right direction
Here's a new version
public class TaskTracker
{
public delegate void AllTasksCompletedHandler(object sender);
public delegate void TaskStartedHandler();
public event AllTasksCompletedHandler AllTasksCompleted;
public event TaskStartedHandler TaskStarted;
private object syncLock = new object();
private SynchronizedCollection<Task> tasksCollection;
private bool isTaskStartedNotified;
private readonly uint delay;
public TaskTracker(uint delayBeforeRemovingTasks)
{
tasksCollection = new SynchronizedCollection<Task>();
delay = delayBeforeRemovingTasks;
}
public void Add(Task task)
{
if (!isTaskStartedNotified)
{
isTaskStartedNotified = true;
TaskStarted?.Invoke();
}
task.ContinueWith(t =>
{
RemoveTask(t);
});
tasksCollection.Add(task);
}
private async void RemoveTask(Task task)
{
await Task.Delay(300);
await Task.Run(() =>
{
tasksCollection.Remove(task);
if (tasksCollection.Count == 0)
{
isTaskStartedNotified = false;
AllTasksCompleted?.Invoke(tasksCollection);
}
});
}
}
I need a windows service to transfer data to another SQL server every 10 minutes.
This service is scheduled with a periodicity of 10 minutes and executes 5 stored procedures that transfer the data
If machine restarts the service should work again.
So, What's best way for this service?
My solution is as below. But this service will stop after the first time:
static class Program
{
static void Main()
{
#if DEBUG
Service1 myService = new Service1();
myService.OnDebug();
#else
var servicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(servicesToRun);
#endif
}
public partial class Service1 : ServiceBase
{
Thread _worker;
static readonly AutoResetEvent StopRequest = new AutoResetEvent(false);
private static IDataRepository _dataRepository;
public Service1()
{
_dataRepository = new DataRepository();
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
_worker = new Thread(DoWork);
_worker.Start();
}
protected override void OnStop()
{
StopRequest.Set();
_worker.Join();
}
private static void DoWork()
{
for (;;)
{
if (!_dataRepository.CheckInternetConnection()) return;
if (!_dataRepository.CheckDatabaseConnection()) return;
if (!_dataRepository.CheckOppositeDatabaseConnection()) return;
if (StopRequest.WaitOne(10000)) return;
List<Test> comeResults = _dataRepository.CheckNewDataCashRegister();
if (comeResults == null) return;
bool sendTest = _dataRepository.SendTest(comeResults);
if (!sendTest) return;
}
}
}
If you want to minimize external dependencies like using the Task Scheduler you can schedule the work in the service like this:
public partial class Service1 : ServiceBase
{
private readonly CancellationTokenSource _cancellationTokenSource;
private static IDataRepository _dataRepository;
public Service1()
{
_dataRepository = new DataRepository();
_cancellationTokenSource = new CancellationTokenSource();
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
ScheduleWorkAsync();
}
protected override void OnStop()
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
}
private async Task ScheduleWorkAsync()
{
var _cancellationToken = _cancellationTokenSource.Token;
while (!_cancellationTokenSource.IsCancellationRequested)
{
try
{
DoWork();
await Task.Delay(TimeSpan.FromMinutes(10), _cancellationToken);
}
catch (OperationCanceledException)
{
}
}
}
private void DoWork()
{
if (!_dataRepository.CheckInternetConnection()) return;
if (!_dataRepository.CheckDatabaseConnection()) return;
if (!_dataRepository.CheckOppositeDatabaseConnection()) return;
List<Test> comeResults = _dataRepository.CheckNewDataCashRegister();
if (comeResults == null) return;
bool sendTest = _dataRepository.SendTest(comeResults);
if (!sendTest) return;
}
}
So i have this Base Class:
public abstract class WiresharkFile : IDisposable
{
private string _fileName;
private int _packets;
private int _packetsSent;
private string _duration;
private double _speed;
private int _progress;
protected abstract WiresharkFilePacket ReadPacket();
public abstract IEnumerator<WiresharkFilePacket> GetEnumerator();
public abstract void Rewind();
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public int Packets
{
get { return _packets; }
set { _packets = value; }
}
public void Dispose()
{
// implemented inside sub class.
}
}
And specific Wireshark format (libpcap):
public class Libpcap : WiresharkFile, IDisposable, IEnumerable<WiresharkFilePacket>
{
private BinaryReader binaryReader;
private Version version;
private uint snaplen;
private int thiszone;
private uint sigfigs;
private LibpcapLinkType linktype;
private long basePos;
private bool byteSwap;
private static uint MAGIC = 0xa1b2c3d4;
private static uint MAGIC_ENDIAN = 0xd4c3b2a1;
public Libpcap(string path)
: this(new FileStream(path, FileMode.Open, FileAccess.Read))
{
FileName = path;
}
private Libpcap(Stream fileStream)
{
...
}
public override void Rewind()
{
binaryReader = new BinaryReader(new FileStream(FileName, FileMode.Open, FileAccess.Read));
binaryReader.BaseStream.Position = basePos;
}
public void Dispose()
{
if (binaryReader != null)
binaryReader.Close();
}
I removed almost all parts of how i am read this file
Add files in to my application
I have this objects list:
public ObservableCollection<WiresharkFile> wiresharkFiles { get; set; }
This list is binding into my ListView.
When the user choose files to add into my application:
string[] files = openFileDialog.FileNames;
I am check this files via another class:
public class FileValidation
{
public static void DoWork(IEnumerable<string> files)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
Task task = Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(files,
new ParallelOptions
{
MaxDegreeOfParallelism = 3
},
file =>
{
ProcessFile(file);
});
}
catch (Exception)
{ }
}, tokenSource.Token,
TaskCreationOptions.None,
TaskScheduler.Default).ContinueWith
(t =>
{
if (FinishValidationEventHandler != null)
FinishValidationEventHandler();
}
, TaskScheduler.FromCurrentSynchronizationContext()
);
}
private static void ProcessFile(string file)
{
ReadWiresharkFormat(file);
using (WiresharkFile wiresharkFile = new Libpcap(file))
{
WiresharkFileInfo.ReadInfo(wiresharkFile);
// Add file into my list.
}
}
private static WiresharkFileFormat ReadWiresharkFormat(string file)
{
using (BinaryReader binaryReader = new BinaryReader(File.Open(file, FileMode.Open, FileAccess.Read)))
{
// Open file and read first 4 bytes in order to verify file type.
}
}
private static void ReadInfo(WiresharkFile wiresharkFile)
{
foreach (WiresharkFilePacket packet in wiresharkFile)
{
// Collect file information (number of packets...)
}
}
}
OK so until here all good.
Now when add many files, lets say (1000+-) i can see that my memory usage is growing in 200MB but after clear this list the memory usage not changed.
Any idea what could cause this ?
How do I capture a key down event in WPF even if my application is not focused?
For me, the best way is this:
public MainWindow()
{
InitializeComponent();
CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
}
void CompositionTarget_Rendering(object sender, EventArgs e)
{
if ((Keyboard.GetKeyStates(Key.W) & KeyStates.Down) > 0)
{
player1.walk();
}
}
The rendering event runs every time.
Global keyboard hook can slow down your debugging.
I prefer to use this approach:
Create KeyboardListener class
public class KeyboardListener : IDisposable
{
private readonly Thread keyboardThread;
//Here you can put those keys that you want to capture
private readonly List<KeyState> numericKeys = new List<KeyState>
{
new KeyState(Key.D0),
new KeyState(Key.D1),
new KeyState(Key.D2),
new KeyState(Key.D3),
new KeyState(Key.D4),
new KeyState(Key.D5),
new KeyState(Key.D6),
new KeyState(Key.D7),
new KeyState(Key.D8),
new KeyState(Key.D9),
new KeyState(Key.NumPad0),
new KeyState(Key.NumPad1),
new KeyState(Key.NumPad2),
new KeyState(Key.NumPad3),
new KeyState(Key.NumPad4),
new KeyState(Key.NumPad5),
new KeyState(Key.NumPad6),
new KeyState(Key.NumPad7),
new KeyState(Key.NumPad8),
new KeyState(Key.NumPad9),
new KeyState(Key.Enter)
};
private bool isRunning = true;
public KeyboardListener()
{
keyboardThread = new Thread(StartKeyboardListener) { IsBackground = true };
keyboardThread.Start();
}
private void StartKeyboardListener()
{
while (isRunning)
{
Thread.Sleep(15);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
if (Application.Current.Windows.Count > 0)
{
foreach (var keyState in numericKeys)
{
if (Keyboard.IsKeyDown(keyState.Key) && !keyState.IsPressed) //
{
keyState.IsPressed = true;
KeyboardDownEvent?.Invoke(null, new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromDependencyObject(Application.Current.Windows[0]), 0, keyState.Key));
}
if (Keyboard.IsKeyUp(keyState.Key))
{
keyState.IsPressed = false;
}
}
}
});
}
}
}
public event KeyEventHandler KeyboardDownEvent;
/// <summary>
/// Состояние клавиши
/// </summary>
private class KeyState
{
public KeyState(Key key)
{
this.Key = key;
}
public Key Key { get; }
public bool IsPressed { get; set; }
}
public void Dispose()
{
isRunning = false;
Task.Run(() =>
{
if (keyboardThread != null && !keyboardThread.Join(1000))
{
keyboardThread.Abort();
}
});
}
}
Subscribe to KeyboardDownEvent in code-behind (or where you need it).
public partial class MainWindow : Window
{
private KeyboardListener listener;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
listener = new KeyboardListener();
listener.KeyboardDownEvent += ListenerOnKeyPressed;
}
private void ListenerOnKeyPressed(object sender, KeyEventArgs e)
{
// TYPE YOUR CODE HERE
}
private void Window_OnUnloaded(object sender, RoutedEventArgs e)
{
listener.KeyboardDownEvent -= ListenerOnKeyPressed;
}
}
Done
See this questions for hooking the keyboard Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#
I've created some simple custom ModuleManager in my silverlight application based on PRISM. I also registered this type in bootstrapper, but PRISM still use the default manager. The constructor of my CustomModuleManager is called, but the property ModuleTypeLoaders is never accessed. I can't figure it out, how can I make it work properly?
Here is bootstrapper.cs
protected override void ConfigureContainer()
{
Container.RegisterType<IShellProvider, Shell>();
Container.RegisterType<IModuleManager, CustomModuleManager>();
base.ConfigureContainer();
}
CustomModuleManager.cs
public class CustomModuleManager : ModuleManager
{
IEnumerable<IModuleTypeLoader> _typeLoaders;
public CustomModuleManager(IModuleInitializer moduleInitializer,
IModuleCatalog moduleCatalog,
ILoggerFacade loggerFacade)
: base(moduleInitializer, moduleCatalog, loggerFacade)
{
MessageBox.Show("ctor");
}
public override IEnumerable<IModuleTypeLoader> ModuleTypeLoaders
{
get
{
MessageBox.Show("getter");
if (_typeLoaders == null)
{
_typeLoaders = new List<IModuleTypeLoader>
{
new CustomXapModuleTypeLoader()
};
}
return _typeLoaders;
}
set
{
MessageBox.Show("setter");
_typeLoaders = value;
}
}
}
CustomXapModuleTypeLoader.cs
public class CustomXapModuleTypeLoader : XapModuleTypeLoader
{
protected override IFileDownloader CreateDownloader()
{
return new CustomFileDownloader();
}
}
CustomFileDownloader.cs
public class CustomFileDownloader : IFileDownloader
{
public event EventHandler<DownloadCompletedEventArgs> DownloadCompleted;
readonly FileDownloader _dler = new FileDownloader();
public CustomFileDownloader()
{
_dler.DownloadCompleted += DlerDownloadCompleted;
}
void DlerDownloadCompleted(object sender, DownloadCompletedEventArgs e)
{
_dler.DownloadCompleted -= DlerDownloadCompleted;
if (DownloadCompleted != null)
{
if (e.Cancelled || e.Error != null)
{
DownloadCompleted(this, e);
}
else
{
DownloadCompleted(this,
new DownloadCompletedEventArgs(e.Result,
e.Error,
e.Cancelled,
e.UserState));
}
}
}
public void DownloadAsync(Uri uri, object userToken)
{
_dler.DownloadAsync(uri, userToken);
}
}
Reorder your call to base.ConfigureContainer so that yours wins (last one wins):
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IShellProvider, Shell>();
Container.RegisterType<IModuleManager, CustomModuleManager>();
}