currently in my application code is written like below and we are facing the memory leak issues
Here the container is holding all the layers object and not relasing them.
var container = builder.Build()
host.AddDependencyInjectionBehavior(mainInterface, container);
Instead of this can i write like, is it recommended
var container = builder.Build()
host.AddDependencyInjectionBehavior(mainInterface,container.BeginLifetimeScope()());
When ever you begin a new LifetimeScope, remember to dispose it once you finish with it. During the LifetimeScope dispose, Autofac disposes all the IDisposable instances it has created.
Related
I have a very, very basic MonoGame game (almost just a new project, with just a single image drawn on screen).
In my Game class, I created an instance of StandardKernel. In LoadContent, I bind it to my SpriteBatch:
protected override void LoadContent ()
{
// Create a new SpriteBatch, which can be used to draw textures.
this.SpriteBatch = new SpriteBatch (GraphicsDevice);
// Setup DI bindings
this.Kernel.Bind<SpriteBatch>().ToConstant<SpriteBatch>(this.spriteBatch);
//TODO: use this.Content to load your game content here
}
(The debugger hits this line.) Later, I try to consume it:
protected void LoadSpritesLater() {
var spriteBatch = Game.Instance.Kernel.Get<SpriteBatch>();
}
For some reason, this line always throws a NullReferenceException. I've verified that Game.Instance.Kernel returns me a StandardKernel instance, that I expect.
Oddly, if I replace the Bind call with a setter (eg. this.SpriteBatch = spriteBatch), I can fetch it in LoadSpritesLater and use it without issue.
I checked the Ninject source code and docs to see if the instance is created through Ninject itself (it seems like it isn't). I don't see why this isn't working.
Having a WCF service and a Consumer I'm not really sure how to handle the Open and Close methods and the lifetime of my Client.
I created the client myself extending and implementing ClientBase and IMyService. Let's call it MyServiceClient
One place I use it for example is MembershipProvider. So I gave MembershipProvider a MyClient as member variable.
I would like to have it instanced once in the MembershipProvider (via IoC container) and then perhaps do a Open and Close call inside every method call in the client.
public bool ValidateUser(string username, string password)
{
this.Open();
bool b = Channel.ValidateUser(username, password);
this.Close();
return b;
}
Is this the right way to go about it. I don't really understand what's really happening when open/close is called and how having one instance of client affects the service (if at all).
One of the problems with using a single client (WCF proxy) instance is that when a fault occurs the proxy enters a faulted state, and it cannot be reused or Dispose-d, only Abort-ed and created anew. On the other hand, if you use/require Sessions on the service side you need the same proxy instance across multiple calls.
In any case, if you would like to use proxy now and worry about transport, sessions or faults later I suggest a wrapper like this that I use for my WCF proxies:
TResult ExecuteServiceMethod<TResult>(Func<MyService, TResult> method)
{
var proxy = new MyService(); //...Or reuse an existing if not faulted
try
{
return method(proxy);
}
catch(Exception e)
{
//...Handle exceptions
}
finally
{
//...Per-call cleanup, for example proxy.Abort() if faulted...
}
}
and you call your service methods like this:
var result = ExecuteServiceMethod((MyService s) => s.VerifyUser(username, password));
Replace MyService with your actual client type. This way you can later change your opening/closing/reusing strategy, add logging, etc. for all service calls by adding code before or after the line return method(client).
I have a WCF service hosted in a Windows Service (running under Local System). I am running a System.Timer inside it. The Operation o1, that initializes the Timer, is declared over a http endpoint over webHttpBinding.
I enabled tracing for System.ServiceModel and from the .svcLog file I checked the Listen Duration for the Operation o1. It shows that, after running for approx 20 hours the Listening at the http endpoint just stops.
I think the this due to the fact that no incoming message arrived at that endpoint. The issue here is with the Listening coming to a stop, my timer(which was initialized inside that particular Operation o1) also stops!
Is there a recommended way to keep the Listener, and hence the timer, up for long durations?
Can we periodically ping the o1 Operation to keep it in memory?
Also, my timer variable that I initialize inside the Operation o1 is an instance variable, isn't this variable expected to be in memory (the WCF being a Singleton) even if the Listener closes??
Thanks so much.
Code Exceprts-
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class SchedulerWindows : ISchedulerWindows
{
///.........all instance variables.....
DataTimer timer = null; /**DataTimer wraps a System.Timers timer variable**/
public List<DataTimer> timersInService = new List<DataTimer>();
public ISchedulerWindows.o1(string s1, string s2, /*********/)
{
//..........//
timer = new DataTimer();
}
}
public class DataTimer
{
/****Newly introduced System.Threading.Timer, previously I was using System.Timers.Timer which was dying****/
public System.Threading.Timer thTimer;
private static readonly object dbAccessLock = new object();
private static readonly object thCallbackLock = new object();
public DataTimer()
{
}
public DataTimer(/************/)
{
TimerCallback timerDelegate = new TimerCallback(this.WorkMethod);
EventLogLogger l = new EventLogLogger();
//l.LogMessage("setting up timer ");
thTimer = new Timer(this.WorkMethod, null, 0, period);
}
...
}
EDIT: Changing to System.Threading namespace from System.Timers namespace AND increasing the timed interval fixed it for me. The timer variable doesn't disappear anymore.
The most likely cause for your issue is InstanceContextMode. If you want your service instance to always be in memory you should use Single. You probably have PerSession or PerCall and that would explain why your timer is disappearing. You mention that your service is singleton but the symptoms are very suspicious. The service instance stays in memory until you shutdown host.
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single
)]
From WCF instance management:
The singleton service lives forever, and is only disposed of once the
host shuts down. The singleton is created exactly once when the host
is created.
EDIT: You probably checked that windows service is still running when your listener stops listening and timer disappears. It would also make sense to see if ServiceHost itself stays in memory. You can also put some logging in ServiceHosts 'Closing', 'Closed' and 'Faulted' event handlers.
EDIT 2:
If your timer is disappearing than you should look at how you allocate it. It most likely gets garbage collected. You have to declare it as an instance field that is reachable from live objects. Make it static to be absolutely sure. You do it for DataTimer but it is not clear how the timer is declared and allocated inside DataTimer. Post some code please.
EDIT 3:
You should not create timers in the operation. What happens if operation get called more than once? What happens to the old timer? I don't see how you close/dispose it. You also seem to have two constructors for DataTimer. One of them is doing nothing. And on top of that you have separate list of timers. This is a bit convoluted. Please isolate the problem and maybe post new code after that.
I've not come across this issue specifically - however, if you just want the timer running while the service is running why not make it static. Then your instance context mode and instance lifetime won't affect your functionality.
I'm trying to find an elegant way to retry an operation when a WCF channel is in faulted state. I've tried using the Policy Injection AB to reconnect and retry the operation when a faulted state exception occurs on first call, but the PolicyInjection.Wrap method doesn't seem to like wrapping the TransparentProxy objects (proxy returned from ChannelFactory.CreateChannel).
Is there any other mechanism I could try or how could I try get the PIAB solution working correctly - any links, examples, etc. would be greatly appreciated.
Here is the code I was using that was failing:
var channelFactory = new ChannelFactory(endpointConfigurationName);
var proxy = channelFactory.CreateChannel(...);
proxy = PolicyInjection.Wrap<IService>(proxy);
Thank you.
I would rather use callback functions, something like this:
private SomeServiceClient proxy;
//This method invokes a service method and recreates the proxy if it's in a faulted state
private void TryInvoke(Action<SomeServiceClient> action)
{
try
{
action(this.proxy);
}
catch (FaultException fe)
{
if (proxy.State == CommunicationState.Faulted)
{
this.proxy.Abort();
this.proxy = new SomeServiceClient();
//Probably, there is a better way than recursion
TryInvoke(action);
}
}
}
//Any real method
private void Connect(Action<UserModel> callback)
{
TryInvoke(sc => callback(sc.Connect()));
}
And in your code you should call
ServiceProxy.Instance.Connect(user => MessageBox.Show(user.Name));
instead of
var user = ServiceProxy.Instance.Connect();
MessageBox.Show(user.Name);
Although my code uses proxy-class approach, you can write a similar code with Channels.
Thank you so much for your reply. What I ended up doing was creating a decorator type class that implemented the interface of my service, which then just wrapped the transparent proxy generated by the ChannelFactory. I was then able to use the Policy Injection Application Block to create a layer on top of this that would inject code into each operation call that would try the operation, and if a CommunicationObjectFaultedException occurred, would abort the channel, recreate it and retry the operation. It's working great now - although it works great, the only downside though is the wrapper class mentioned having to implement every service operation, but this was the only way I could use the PIAB as this made sense for me for in case I did find a way in future, it was easy enough to change just using interfaces.
I'm trying to make calls sync. But silverlight app locks itself when calling endList method. In a simple console app i can make async to sync. Could not see the problem.
var svc = new WcfServiceClient();
var ar = svc.BeginList(null, null);
var result = svc.EndList(ar); <-- Silverlight hangs here
listBox.ItemsSource = result;
Silverlight doesn't support Sync calls.
Here is a article about synchronous calls to webservices and a workaround.
Short answer: You can do that if you are not on the Dispatcher thread, something like:
System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
IAsyncResult asyncResult = svc.BeginSomething(null, null);
if (!asyncResult.CompletedSynchronously)
{
asyncResult.AsyncWaitHandle.WaitOne();
}
try
{
svc.EndSomething(asyncResult);
}
catch
{
throw;
}
finally
{
asyncResult.AsyncWaitHandle.Close();
}
});
The big advantage of this is that you can keep your domain model layer synchronously like in the old days, you can implement lazy loading easily etc...
But in practice you can only use it when you design your application to strictly adhere to the MVVM / Commanding patterns, where your ViewModels and Commands handle the switching between the dispatcher thread and the model threads. It's a lot of ground work to do, and there are some gotchas, but when it works, it works wonderfully.
If you want to use ready-to-use framework that works similarly, it is available here: CodeProject: Introducing the Model Thread View Thread Pattern. The architecture is explained very well too on that page.