I have a Director that supplies Builders to Threads.
Once an event is fired I need to dispose the Builder as it holds native resources BUT only when all Threads are done.
I keep the builders in a Cache so it's possible to think of it as to Dispose when number of references is zero if the director release the Builder.
I know about the circular references problem and It's not relevant in this scenario because only the Director supplies the references.
I know that I should implement the Finalize,SuppressFinalize pattern to avoid memory leak if thread died before disposing the Builder.
Consider the following example where its hard to tell who should actually dispose the builder:
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleApplication4
{
class Program
{
static void Main()
{
var builderId = 1;
var dictionary = new Dictionary<int, MyBuilder> {{builderId, new MyBuilder()}};
var director = new Director(dictionary);
for (var i =0 ; i < 5; i++)
{
new Worker(director.GetBuilder(builderId));
}
director.Dispose(builderId);
Thread.Sleep(10000);
}
}
public class Director
{
private readonly Dictionary<int, MyBuilder> _cache;
public Director(Dictionary<int, MyBuilder> cache)
{
this._cache = cache;
}
public MyBuilder GetBuilder(int i)
{
MyBuilder builder;
_cache.TryGetValue(i, out builder);
return builder;
}
public void Dispose(int i)
{
MyBuilder builder;
_cache.TryGetValue(i, out builder);
builder?.Dispose();
}
}
public class MyBuilder :IDisposable
{
public void Dispose()
{
Console.WriteLine("Should I dispose?");
}
public void Build()
{
Console.WriteLine("Build");
}
}
public class Worker
{
public void Work(MyBuilder builder)
{
builder.Build();
builder.Dispose();
}
public Worker(MyBuilder builder)
{
var t = new Thread(() => Work(builder));
t.Start();
}
}
}
Related
I would like to convert a blocking IEnumerable (possibly infinite) into messages sent to an Actor. What is the best way to do this? I am currently attempting to create a Task within an actor on PreStart and inside the task have it send messages to but it doesn't seem to be working.
I've read some pages about preferring to use PipeTo to wrap a Task but that seems to only be used to retrieve a single result rather than have a separate process continually sending values.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Akka.Actor;
namespace Junk
{
public class Program
{
public static void Main()
{
var system = ActorSystem.Create("my-system");
var actor = system.ActorOf(Props.Create(() => new Manager()));
Console.ReadLine();
}
}
public class Manager : ReceiveActor
{
private Task _task;
public Manager() {
Receive<uint>(msg => { Console.WriteLine($"received {msg}"); });
}
protected override void PreStart() {
Console.WriteLine($"{Self} - PreStart --------------");
startTask();
}
private void startTask() {
_task = Task.Factory.StartNew(() => {
BlockingEnumerable source = new BlockingEnumerable();
Console.WriteLine($"task starting loop -------------");
foreach (uint v in source) {
Self.Tell(v);
}
});
}
}
public class BlockingEnumerable : IEnumerable<uint>
{
public IEnumerator<uint> GetEnumerator() { return new BlockingEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
public class BlockingEnumerator : IEnumerator<uint>
{
private uint value = 0;
public uint Current => value;
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext() { Thread.Sleep(2000); value += 1; return true; }
public void Reset() { value = 0; }
}
}
I have a class (Service) that receives 2 arguments (an IClient and an ICounter).
I want Unity to inject the same instance for both (a Decorator that implements both interfaces).
But how?
And one more thing: I want Unity to inject the same instance to Service using a per-thread basis. This is, in each a thread, each time container.Resolve<Service>() is invoked, the same instance of Decorator should be injected to both arguments of Service
This is the code I have so far. I only registers the types and it runs, but 3 instances of the Decorator class are created. In this case, with only one thread, only one instance of Decorator should be created.
You can run it with DotNetFiddle: https://dotnetfiddle.net/Widget/m3PRQz
using System;
using Microsoft.Practices.Unity;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType<IClient>(new InjectionFactory(c => new Decorator(c.Resolve<Client>())));
container.RegisterType<ICounter, Decorator>();
container.Resolve<Service>();
Console.WriteLine(Decorator.NumberOfInstances + " instances of Decorator have been created");
}
}
public class Client : IClient
{
}
public class Decorator : IClient, ICounter
{
public static int NumberOfInstances { get; private set; }
public Decorator(IClient client)
{
NumberOfInstances++;
}
}
public interface ICounter
{
}
public interface IClient
{
}
public class Service
{
public Service(IClient client, ICounter counter)
{
}
}
}
EDIT: If I wasn't using DI, I would write this code. Keep in mind I don't invoke any method, for simplicity.
public class Program
{
public static void Main(string[] args)
{
var t1 = Task.Run(() => CreateService());
var t2 = Task.Run(() => CreateService());
}
private static Service CreateService()
{
var decorator = new Decorator(new Client());
return new Service(decorator, decorator);
}
}
You can try something like this:
register Decorator per thread:
container.RegisterType<Decorator>(
new PerThreadLifetimeManager(),
new InjectionFactory(c => new Decorator(c.Resolve<Client>())));
map interfaces to decorator:
container.RegisterType<ICounter, Decorator>();
container.RegisterType<IClient, Decorator>();
I am trying to get AutoFac Delegate Factories & Type Interceptors to play nicely with each other, but I cannot seem to get the behaviour I want.
(http://docs.autofac.org/en/latest/advanced/delegate-factories.html)
(http://docs.autofac.org/en/latest/advanced/interceptors.html)
In the example below, I want calls to the IQuoteService.GetQuote(...) to be intercepted by the CallLogger interceptor.
I've tried both of the Enable___(); extension methods for enabling interception, but none of them seem to correctly intercept the call.
I suspect the problem is the way that Autofac is registering the proxy and the signature of the delegate, but to be honest I am a little stuck... I don't know Autofac as well as I know Castle Windsor, but this project is using Autofac.
ANSWERED BELOW
Code updated to working example:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autofac;
using Autofac.Extras.DynamicProxy2;
using Castle.DynamicProxy;
namespace AutofacTest
{
public class Shareholding
{
public delegate Shareholding Factory(string symbol, uint holding);
private readonly IQuoteService _quoteService;
public Shareholding(string symbol, uint holding, IQuoteService quoteService)
{
_quoteService = quoteService;
Symbol = symbol;
Holding = holding;
}
public string Symbol { get; private set; }
public uint Holding { get; set; }
public decimal Value
{
get { return _quoteService.GetQuote(Symbol) * Holding; }
}
}
public class Portfolio
{
private readonly IList<Shareholding> _holdings = new List<Shareholding>();
private readonly Shareholding.Factory _shareholdingFactory;
public Portfolio(Shareholding.Factory shareholdingFactory)
{
_shareholdingFactory = shareholdingFactory;
}
public decimal Value
{
get { return _holdings.Sum(h => h.Value); }
}
public void Add(string symbol, uint holding)
{
_holdings.Add(_shareholdingFactory(symbol, holding));
}
}
public interface IQuoteService
{
decimal GetQuote(string symbol);
}
public class QuoteService : IQuoteService
{
public decimal GetQuote(string symbol)
{
return 10m;
}
}
public class CallLogger : IInterceptor
{
private readonly TextWriter _output;
public CallLogger(TextWriter output)
{
_output = output;
}
public void Intercept(IInvocation invocation)
{
_output.Write("Calling method {0} with parameters {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
_output.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<Shareholding>();
builder.RegisterType<Portfolio>();
builder.Register(c => new CallLogger(Console.Out));
builder.RegisterType<QuoteService>()
.As<IQuoteService>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(CallLogger));
var container = builder.Build();
var portfolio = container.Resolve<Portfolio>();
portfolio.Add("ABC", 1234);
portfolio.Add("DEF", 4567);
Console.WriteLine(portfolio.Value);
Console.ReadKey();
}
}
}
// Magic?
builder.RegisterType<Portfolio>()
.As<IPortfolio>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(CallLogger));;
builder.Register(c => new CallLogger(Console.Out));
var container = builder.Build();
var isResolved = container.Resolve<IPortfolio>();
It looks to me like you are missing an association between the DynamicProxy for IPortfolio and the IInterceptor type.
This can be remedied via registration:
builder.RegisterType<Portfolio>()
.As<IPortfolio>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(CallLogger));
or via the InterceptAttribute
[Intercept(typeof(CallLogger))]
public interface IPortfolio
{
decimal Value { get; }
void Add(string symbol, uint holding);
}
I have the following classes
public class A
{
protected static Dictionary<string,Func<BaseClass>> dict = new Dictionary<string,Func<BaseClass>>();
public static void AddGenerator(string type,Func<BaseClass> fncCreateObject)
{
dict.Add(type,fncCreateObject);
}
}
class B : BaseClass
{
static B()
{
A.AddGenerator("b",CreateObject);
}
protected B()
{}
pulic static B CreateObject()
{
return new B();
}
}
NOTE: The above code is simply an example but very closely relates to the what I'm trying to achieve.
Many people would advice using an IoC container such as NInject or Unity but my main reason for this post if to figure out why the above code does not execute as it is expected to.
So, in the above code, I'm expecting class B's static constructor to call on the static method of class A and an entry should be available in the dictionary for the rest of the application life cycle.
However, when I run the code and debug, I found that the dictionary is empty.
Why is the code invoked from class B's static constructor not executing?
From the documentation:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
Clearly, at the point in your code where you inspect the dictionary, no instance has yet been created, and no static members have been referenced.
Not exactly a 1:1 translation, of your sample into MEF, but it should give you a good idea what MEF is capable of:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
private List<IBType> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.GetType());
}
}
}
[Export(typeof(IBType))]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
class B2:IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething() { }
}
interface IBType
{
void DoSomething();
}
}
I've also included the safest implementation of a Singleton pattern known to me. MEF will allow you to source many implementations of the same interface which are resolved dynamically at runtime. I used it also with metadata attributes, like version and name.
But if you need it to work with a base abstract class, check out this article.
The same code as above, but with metadata attributes use sample:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
a.BTypes.Single(s=>s.Metadata.Name.Equals("Second")).Value.DoSomething();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
public List<Lazy<IBType,IBTypeMetadata>> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.Value.GetType());
}
}
}
[Export(typeof(IBType))]
[BTypeMetadata("First")]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
[BTypeMetadata("Second")]
class B2 : IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething()
{
Console.WriteLine("Hello from Second");
}
}
public interface IBType
{
void DoSomething();
}
public interface IBTypeMetadata
{
string Name { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class BTypeMetadataAttribute : ExportAttribute
{
public string Name { get; set; }
public BTypeMetadataAttribute(string name)
: base(typeof(IBTypeMetadata)) { Name = name; }
}
}
IMHO, MEF might help you as long as your plan is to call some public methods from a particular instance of any of the B-types. In your sample, you simply create new instances of a B-type, and I think there is more to it than what your sample shows.
MEF will create catalogs for you from your currently loaded assembly, as well as any number of assemblies from any number of directories. You can even have it dynamically re-composable, meaning, at runtime, you could potentially retrieve a DLL from a server, and have it added to your catalog without shutting down the application.
MEF is also hierarchical, so your B-types can have their own "catalogs". And to wire it all up, all you have to do is to call SatifyImportsOnce passing an instance of class A.
I created a sample project to model what I faced in my real project.
The problem is that when I query some external data in a cycle (in the real life my project queries windows to find match(es), and stops querying on success or on timeout expiration). It seems to me that NInject does not dispose created objects and consider the cycle as one long call.
How to work around this situation? Maybe, cut out the code that fills list and put it into another class? Or simply, could you make my sample project better?
The link on Github or its code below:
public interface IMyObj : IDisposable
{
string Name { get; set; }
}
public class MyObj : IMyObj
{
public virtual string Name { get; set; }
public virtual void Dispose()
{
Name = string.Empty;
GC.SuppressFinalize(this);
}
}
public class NjModule : NinjectModule
{
public override void Load()
{
Bind<IMyObj>()
.To<MyObj>()
.InCallScope();
Bind<Requester>()
.ToSelf()
.InSingletonScope();
}
}
public class Requester
{
public List<IMyObj> RequestObjects()
{
List<IMyObj> list = new List<IMyObj>();
for(int i = 0; i < 10; i++) {
var myObj = Program.Kernel.Get<IMyObj>();
myObj.Name = "abcdefghijklmnopqrstuvwxyz";
list.Add(myObj);
}
return list;
}
}
class Program
{
public static IKernel Kernel;
public static void Main(string[] args)
{
Console.WriteLine("Hello NInject!");
// TODO: Implement Functionality Here
Kernel = new StandardKernel(new NjModule());
Kernel.Settings.ActivationCacheDisabled = true;
var requester = Kernel.Get<Requester>();
for (int i = 0; i < 100000000; i++) {
List<IMyObj> list =
requester.RequestObjects();
foreach (MyObj listItem in list) {
listItem.Dispose();
}
list.Clear();
list = null;
}
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
I fixed the problem with memory by using ChildKernel. At the moment, I can't say anything about performance, however the memory leak is definitely fixed: the project started at 10MB and works on 15-25MB.
Anyway, I'd be glad to consider other alternatives to my solution if you, the stackoverflowers, have such.
My solution is here (Github) and the below:
public interface IMyObj : IDisposable
{
string Name { get; set; }
}
public class MyObj : IMyObj
{
public virtual string Name { get; set; }
public virtual void Dispose()
{
Name = string.Empty;
GC.SuppressFinalize(this);
}
}
public class NjModule : NinjectModule
{
public override void Load()
{
Bind<Requester>()
.ToSelf()
.InSingletonScope();
Bind<IChildKernel>().ToSelf().InSingletonScope();
}
}
public class NjChildKernelModule : NinjectModule
{
public override void Load()
{
Bind<IMyObj>()
.To<MyObj>()
.InCallScope();
}
}
public class Requester
{
public List<IMyObj> RequestObjects(IChildKernel childKernel)
{
List<IMyObj> list = new List<IMyObj>();
for(int i = 0; i < 10; i++) {
var myObj = childKernel.Get<IMyObj>();
myObj.Name = "abcdefghijklmnopqrstuvwxyz";
list.Add(myObj);
}
return list;
}
}
class Program
{
public static IKernel Kernel;
public static void Main(string[] args)
{
Console.WriteLine("Hello NInject!");
// TODO: Implement Functionality Here
Kernel = new StandardKernel(new NjModule());
Kernel.Settings.ActivationCacheDisabled = true;
var requester = Kernel.Get<Requester>();
for (int i = 0; i < 100000000; i++) {
var childKernel = new ChildKernel(Kernel, new NjChildKernelModule());
childKernel.Settings.ActivationCacheDisabled = true;
List<IMyObj> list =
requester.RequestObjects(childKernel);
foreach (MyObj listItem in list) {
listItem.Dispose();
}
list.Clear();
list = null;
childKernel.Dispose();
}
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
If think there is a misconception here.
I think InCallScope is not doing what you think it is. Have a look at the following integration test for InCallScope:
this.kernel.Bind<Parent>().ToSelf();
this.kernel.Bind<Child>().ToSelf().InCallScope();
this.kernel.Bind<IGrandChild>().To<GrandChild>().InCallScope();
var parent1 = this.kernel.Get<Parent>();
var parent2 = this.kernel.Get<Parent>();
parent1.Dispose();
parent1.FirstChild.Should().BeSameAs(parent1.SecondChild);
parent1.GrandChild.Should().BeSameAs(parent1.FirstChild.GrandChild);
parent1.FirstChild.Should().NotBeSameAs(parent2.FirstChild);
parent1.GrandChild.Should().NotBeSameAs(parent2.GrandChild);
parent1.FirstChild.IsDisposed.Should().BeTrue();
parent1.FirstChild.GrandChild.IsDisposed.Should().BeTrue();
parent2.FirstChild.IsDisposed.Should().BeFalse();
parent2.FirstChild.GrandChild.IsDisposed.Should().BeFalse();
parent2.Dispose();
parent2.FirstChild.IsDisposed.Should().BeTrue();
parent2.FirstChild.GrandChild.IsDisposed.Should().BeTrue();
(Source: https://github.com/ninject/ninject.extensions.namedscope/blob/master/src/Ninject.Extensions.NamedScope.Test/NamedScopeIntegrationTest.cs)
As you can see the IChild is instantiated in the scope of Parent. IChild is disposed as soon as Parent is disposed.
In your example, Requester is bound InSingletonScope. Everything which is instantiated for / by Requester in its InChildScope will only be disposed once Requester is disposed.
However, since you don't seem to be using ContextPreservation in your original Requester there is actually not even a scope for your IMyObj.
How would you like it to work?