Ninject with EF multithreading - c#

Good morning everyone!
I just started working in the project where I see there is an memory leak.
The situtation is as below. There is a console application which basically runs all the time in the while(true) loop.
There are bunch on classes which does some logic in the loop.
Each class has Execute() method where inside create uses Task.Run() method where the call is not awaited by anyone.
The list of above classes are called Engines. All engines are stateless classes which are stored in in array in main Program.cs class.
The code basically looks like:
private static List<BaseEngine> Engines;
public static void Main(string[] args)
{
InitializeDI();
RunProgram();
}
private static void RunProgram()
{
while (true)
{
try
{
foreach (var engine in Engines)
{
engine.Execute();
}
}
catch (Exception ex)
{
//handle
}
finally
{
Thread.Sleep(TimeSpan.FromSeconds(3));
}
}
}
private static void InitializeDI()
{
_kernel = new StandardKernel();
ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(_kernel));
NinjectConfig.Setup(_kernel);
}
The sample engine looks like:
public class SampleEngine : BaseEngine
{
public override void Execute(Task task)
{
var someService = ServiceLocator.Current.GetInstance<IDbContext>();
System.Threading.Tasks.Task.Run(() =>
{
// some action using dbcontext
});
}
}
In above example of SampleEngine it uses to get IDbContext from Ninject DI. However other engines could use another services regiestred in DI.
All the dependencies are registered as InCallScope()
Basically its like mostly all engine its about fire and forget the given method using Task.Run().
What I did is changed Execute method to return the Task and after this task ran to completion I used to Dispose() this task. This did not bring any value.
I did some investigations and I saw that the problem is inside Ninject.Activation.Cache. I can do the manual cache clean which helps but I know the problem is somewhere in the code but I cannot find it.
Since every dependency is registered as InCallScope() they should be disposed after each task begin to the end. I dont see anything holding reference to these objects because every engine is stateless .
I used ANTS to see the some information and this just keeps growing each minute:
And this points to the Ninject caching as below:
Looks like the DbContext is not disposed and still exist in Ninject cache. Is it a problem of alot of tasks in the system or I do anything wrong ?
Thanks in advance
Cheers!

The most simple approach seems to be embedding the using in your task. But it is a blind shot, as it seems your code is simplified. You don't use the task parameter in your method.
public class SampleEngine : BaseEngine
{
public override void Execute(Task task)
{
System.Threading.Tasks.Task.Run(() =>
{
using (var someService = ServiceLocator.Current.GetInstance<IDbContext>())
{
// some action using dbcontext
}
});
}
}
For a more advanced approach, here is an interesting link. It features a InTaskScope binding. It is based on AsyncLocal and custom tasks through extensions of TaskFactory

Related

In a c# service with a longRunning Async main method, should you .wait in the service startup, store the Task somewhere, or ignore it entirely?

In a lot of our services, the OnStart method calls a neverEnding async Task and .Wait() which does all the service work until it gets manually shut down. We do something like the following (and have been since before I came onto the scene).
MyServiceClass service;
protected override void OnStart(string[] args)
{
eventLog.WriteEntry("MyService service is starting up.");
service = new MyServiceClass(this.ServiceName);
}
...
public class MyServiceClass
{
public MyServiceClass() {
Task.Run(() => DoServiceWork()).Wait();
}
public async Task DoServiceWork() {
while (true)
{
await Task.Delay(1000);//pretend this is actual work being done
}
}
}
Is there any reason not to just store the task and move on? (assuming the main method has appropriate exception handling)
public class MyServiceClass
{
public Task taskToBeAwaitedOnServiceStop;
public MyServiceClass() {
taskToBeAwaitedOnServiceStop = Task.Run(() => DoServiceWork());
}
}
or just to ignore the task entirely
public class MyServiceClass
{
public MyServiceClass() {
_ = DoServiceWork();
}
}
I'm considering the options as we don't like having .waits floating around (and having less means less to check when we go hunting). I'm asking here to be certain my alternatives won't cause strange service logic if implemented.
I hope this isn't too stupid a question, thanks for any help :)

How to efficiently count HTTP Calls in asp.net core?

I have an abstract class called HttpHelper it has basic methods like, GET, POST, PATCH, PUT
What I need to achieve is this:
Store the url, time & date in the database each time the function is called GET, POST, PATCH, PUT
I don't want to store directly to the database each time the functions are called (that would be slow) but to put it somewhere (like a static queue-memory-cache) which must be faster and non blocking, and have a background long running process that will look into this cache-storage-like which will then store the values in the database.
I have no clear idea how to do this but the main purpose of doing so is to take the count of each calls per hour or day, by domain, resource and url query.
I'm thinking if I could do the following:
Create a static class which uses ConcurrentQueue<T> to store data and call that class in each function inside HttpHelper class
Create a background task similar to this: Asp.Net core long running/background task
Or use Hangfire, but that might be too much for simple task
Or is there a built-in method for this in .netcore?
Both Hangfire and background tasks would do the trick as consumers of the queue items.
Hangfire was there before long running background tasks (pre .net core), so go with the long running tasks for net core implementations.
There is a but here though.
How important is to you that you will not miss a call? If it is, then neither can help you.
The Queue or whatever static construct you have will be deleted the time your application crashes/machine restarts or just plain recycling of the application pools.
You need to consider some kind of external Queuing mechanism like rabbit mq with persistence on.
You can also append to a file, but that might also cause some delays as read/write.
I do not know how complex your problem is but I would consider two solutions.
First is calling Async Insert Method which will not block your main thread but will start task. You can return response without waiting for your log to be appended to database. Since you want it to be implemented in only some methods, I would do it using Attributes and Middleware.
Simplified example:
public IActionResult SomePostMethod()
{
LogActionAsync("This Is Post Method");
return StatusCode(201);
}
public static Task LogActionAsync(string someParameter)
{
return Task.Run(() => {
// Communicate with database (X ms)
});
}
Better solution is creating buffer which will not communicate with database each time but only when filled or at interval. It would look like this:
public IActionResult SomePostMethod()
{
APILog.Log(new APILog.Item() { Date = DateTime.Now, Item1 = "Something" });
return StatusCode(201);
}
public partial class APILog
{
private static List<APILog.Item> _buffer = null;
private cont int _msTimeout = 60000; // Timeout between updates
private static object _updateLock = new object();
static APILog()
{
StartDBUpdateLoopAsync();
}
private void StartDBUpdateLoopAsync()
{
// check if it has been already and other stuff
Task.Run(() => {
while(true) // Do not use true but some other expression that is telling you if your application is running.
{
Thread.Sleep(60000);
lock(_updateLock)
{
foreach(APILog.Item item in _buffer)
{
//Import into database here
}
}
}
});
}
public static void Log(APILog.Item item)
{
lock(_updateLock)
{
if(_buffer == null)
_buffer = new List<APILog.Item>();
_buffer.Add(item);
}
}
}
public partial class APILog
{
public class Item
{
public string Item1 { get; set; }
public DateTime Date { get; set; }
}
}
Also in this second example I would not call APILog.Log() each time but use Middleware in combination with Attribute

AutoFac - Initialize heavy-weight singletons on app_start

Our configuration is, MVC5 C# app, using AutoFac.
We have a number of singletons, which if they're initialized with the first request, causes a bad experience for the user, because their initialization takes around 3-4 seconds in total. We're using AutoFac for Dependency injection, I'm wondering if there's any way of making sure the singletons (or these specific ones) are built on App_Start so we don't lose time when the user sends the first request? If not, what's the best way of solving this problem?
The general solution to this type of problem is to hide such heavy weight objects after a proxy implementation. This way you can trigger the initialization process directly at application startup, while the operation runs in the background without requests to be blocked (unless they require the uninitialized data during their request).
In case your code looks like this:
// The abstraction in question
public interface IMyService
{
ServiceData GetData();
}
// The heavy implementation
public class HeavyInitializationService : IMyServic {
public HeavyInitializationService() {
// Load data here
Thread.Sleep(3000);
}
public ServiceData GetData() => ...
}
A proxy can be created as follows:
public class LazyMyServiceProxy : IMyService {
private readonly Lazy<IMyService> lazyService;
public LazyMyServiceProxy(Lazy<IMyService> lazyService) {
this.lazyService = lazyService;
}
public ServiceData GetData() => this.lazyService.Value.GetData();
}
You can use this proxy as follows:
Lazy<IMyService> lazyService = new Lazy<IMyService>(() =>
new HeavyInitializationService());
container.Register<IMyService>(c => new LazyMyServiceProxy(lazyService))
.SingleInstance();
// Trigger the creation of the heavy data on a background thread:
Task.Factory.StartNew(() => {
// Triggers the creation of HeavyInitializationService on background thread.
var v = lazyService.Value;
});

Mock implementation for use in automatic UI testing

I am working on adding basic automatic UI tests to the block of unit tests we run with each nightly build. We used MSTest coded UI and created a script.
The code-behind is dependent upon IClientManager which both the real manager and mock implement.
My problem is that I don't know how to switch automatically between the real and mock implementations inside the button click handler, when running a test.
My two other constraints are that I can't have a dependency on the mock assembly in the code-behind and that I can't use a DI framework, since the client is "security conscious" and getting a framework approved might take months.
Is there any way of doing this manually, and hopefully, not a bigger problem than the problem I am looking to solve?
Thank you!
You could build your own simple object container if you can't use a third party one (which is silly but I understand, I've been there before)
here is something that I whipped up that could get you started... haven't tested it and it is really rough, but hopefully you get the idea
public static class ObjectFactory
{
static IDictionary<Type, object> _factory = new Dictionary<Type, object>();
public static void Register<T>(Func<T> builder)
{
if (_factory.ContainsKey(typeof(T)))
_factory[typeof(T)] = builder;
else
_factory.Add(typeof(T), builder);
}
public static T GetInstance<T>()
{
if (_factory.ContainsKey(typeof(T)))
throw new ArgumentException(string.Format("Type <{0}> not registered in ObjectFactory", typeof(T).Name));
return ((Func<T>)_factory[typeof(T)])();
}
}
public interface IClientManager { }
public class RealClientManager : IClientManager { }
public class MockClientManager : IClientManager { }
public class MyView
{
public MyView()
{
// probably better to do this registry in some sort of application initialization
ObjectFactory.Register<IClientManager>(() => new RealClientManager());
}
public void SomeMethodThatNeedsClientManager()
{
var clientManager = ObjectFactory.GetInstance<IClientManager>();
}
}
public class MyTester
{
[TestMethod()]
public void SomeTest()
{
var view = new MyView();
// swap the client manager in the test
ObjectFactory.Register<IClientManager>(() => new MockClientManager());
// Asserts
}
}
you can see that if you've used StructureMap or some other DI container before they do a lot of the same thing with a lot of added niceties such as traversing your object graph and registering objects automatically based on conventions, managing object lifecycles, scoping of containers, etc... a lot of this stuff you could implement yourself too... but you should just really used a tried and true solution such as StructureMap

How to determine if .NET code is running in an ASP.NET process?

I have an instance of a general purpose class that will be executed both under
ASP.NET and a stand alone program. This code is sensative to the process where it
is being run - that is, there are certin methods that should not called if
running under ASP.NET. How do you determine if the code is executing in an ASP.NET
process?
The solution I am currently using is answered below.
I wish someone would add a comment as to why this question has gotten downvoted and/or propose a better way to ask it! I can only assume at least some folks have looked at the question and said "what an idiot, ASP.NET code is .NET code".
HttpContext.Current can also be null within ASP.NET if you're using asynchronous methods, as the asynchronous task happens in a new thread that doesn't share the HttpContext of the original thread. This may or may not be what you want, but if not then I believe that HttpRuntime.AppDomainAppId will be non-null anywhere in an ASP.NET process and null elsewhere.
Try this:
using System.Web.Hosting;
// ...
if (HostingEnvironment.IsHosted)
{
// You are in ASP.NET
}
else
{
// You are in a standalone application
}
Worked for me!
See HostingEnvironment.IsHosted for details...
I think what you really want to do is rethink your design. A better way to do this is to use a Factory class that produces different versions of the classes you need (designed to implement interfaces so you can use them interchangeably) depending on how the application is started. This will localize the code to detect web- and non-web-based usage in one place rather than scattering it all over your code.
public interface IDoFunctions
{
void DoSomething();
}
public static class FunctionFactory
{
public static IDoFunctions GetFunctionInterface()
{
if (HttpContext.Current != null)
{
return new WebFunctionInterface();
}
else
{
return new NonWebFunctionInterface();
}
}
}
public IDoFunctions WebFunctionInterface
{
public void DoSomething()
{
... do something the web way ...
}
}
public IDoFunctions NonWebFunctionInterface
{
public void DoSomething()
{
... do something the non-web way ...
}
}
using System.Diagnostics;
if (Process.GetCurrentProcess().ProcessName == "w3wp")
//ASP.NET
This is my answer to the question.
First, make sure your project references System.Web and that your code file is "using System.Web;".
public class SomeClass {
public bool RunningUnderAspNet { get; private set; }
public SomeClass()
//
// constructor
//
{
try {
RunningUnderAspNet = null != HttpContext.Current;
}
catch {
RunningUnderAspNet = false;
}
}
}
If HttpContext Is Nothing OrElse HttpContext.Current Is Nothing Then
'Not hosted by web server'
End If

Categories