I have a windows service which keep on looping until it stopped. There is a thread interval of 15 second after each loop. I am using unity container to resolve an object as shown below:
var processes = ProcessConfigurationSection.GetProcesses();
while (!_stopped)
{
try
{
foreach (var process in processes)
{
var worker = new Worker(DiContainer.UnityContainer.Resolve<IProcessDao>());
worker.RunProcess(process.Name, process.StoredProcedure, process.BatchSize);
}
Thread.Sleep(_interval);
}
catch (Exception ex)
{
Log.LogEvent(...);
}
}
Should I create an instance of the worker (and resolve the object) inside the while loop or should it be outside the while loop for performance benefit? Also, is there a chance of memory leak for either of this approach?
You should typically define a scope 'per request'. For a web application this would typically be a scope that lasts for the lifetime of the web request. For a Windows service application however there are still requests, only you have to decide what you see as request. Each RunProcess call could be a single request (thus single scope) or processing the whole batch of processes can be seen as a single request.
You shouldn't define this scope outside the loop because a scoped lifestyle would typically implement things like a unit of work implementations that get reused throughout the request. For instance Entity Framework's DbContext is a unit of work. You wouldn't want to reuse the same DbContext for the lifetime of the application, because when an operation fails, you could corrupt the DbContext and therefore corrupt the complete application.
With Unity scoping is implemented using child containers. You should wrap your request with the following:
using (var child =
DiContainer.UnityContainer.CreateChildContainer())
{
var worker = new Worker(child.Resolve<IProcessDao>());
worker.RunProcess(process.Name, process.StoredProcedure,
process.BatchSize);
}
Or perhaps the using (var child should wrap the foreach. That is something you have to decide.
Related
Is there a way to define a scope for a specific lifestyle? I am attempting to implement my own scope that I want to persist across an application, but internally I also create another scope, and then a request to GetInstance returns the inner scoped instance instead.
I thought if I could define my lifestyle as:
public class MyScopedLifestyle : ExecutionContextScopeLifestyle
{
public MyScopedLifestyle(bool disposeInstanceWhenScopeEnds)
: base("MyScopedLifestyle", disposeInstanceWhenScopeEnds)
{
}
protected override int Length
{
get
{
return 100;
}
}
}
And my usage is:
var container = new Container();
container.Register<IRequestData, RequestData>(new MyScopedLifestyle());
// i had hoped I could say
// container.BeginExecutionContextScope(MyScopedLifestyle)
// or something similar
// this is controlled by me
using (var scope1 = container.BeginExecutionContextScope())
{
// do some stuff
container.GetInstance<IRequestData>().RequestMarket = "en-US";
// this is done via the webapi execution scope (using simpleinjector dependency resolver)
using (var scope2 = container.BeginExecutionContextScope())
{
Assert.Equal("en-US", container.GetInstance<IRequestData>().RequestMarket); // false
}
}
But I'm unsure how to utilize my custom lifestyle when creating the inner execution scope.
What I really want to happen, is that my instance of IRequestData used in scope1, is the same instance of IRequestData inside of scope2. Is this something I can achieve with SimpleInjector?
Edit
I removed the fact that I'm attempting to create an instance of an object per OWIN request, rather than per WebAPI request. Ideally I'm attempting to create:
container.RegisterOwinRequest<IRequestData, RequestData>();
So that when I resolve IFoo anywhere within my pipeline (be it an OWIN middleware, or in the WebAPI part, the same instance is returned for a particular request).
Edit 2
Swapped our IFoo/Foo/MyProperty for better names.
What you're trying to accomplish with a custom lifestyle is absolutely possible, but might not be that easy, because you will have to store that scope somewhere (probably in the CallContext) and need to create a BeginMyCustomScope method that creates a new scope and have a custom Scope implementation that removes itself from the CallContext when Dispose is called. I think this is too much work and too much complexity.
The problem exists because during the time you want to set the RequestMarket property, there is no Web API request scope started. The way to usually force such scope to be started is to call the GetDependencyScope method on the HttpRequestMessage:
message.GetDependencyScope();
Right after that you can resolve the IRequestData and it works as expected:
container.GetInstance<IRequestData>().RequestMarket = "en-US";
I'm unsure however, whether the HttpRequestMessage is available at that point in time, so if not, I think working with a DelegatingHandler as you expressed in the comments is a good alternative.
In the past, a good way to communicate data across the callstack was using thread-specific variables, but that obviously fails when using async/await models as with Web API and OWIN. So the new way to do this is using the CallContext. So instead of using a DelegatingHandler, you might be able to do something like this:
container.RegisterInitializer<IRequestData>(data =>
data.RequestMarket = (string)CallContext.LogicalGetData("RequestMarketKey"));
And when the OWIN request starts, you do this:
CallContext.LogicalSetData("RequestMarketKey", "en-US");
I am using a framework that allow me to intercept in some entry points.
The framework scope is not Web Request, not thread and not transient, its something like thread based, but i saw a lot of places with thread reuse.
So i need a custom scope, where i say where to start and where to end the scope.
Since I have a lot of dependencies, most of them are defined in static contractor, because they are stateless.
I have one dependency that actually need to be injected on every framework interception.
This is the interception method, and how I do the injection (I am not calling this method, the framework does). So what i need here is to inject the AppContext and make sure that Castle always resolve me the correct context (within the scope)
public void Execute(AppContext context)
{
using (var s = CastleContainer.Container.BeginScope())
{
CastleContainer.Container.Register(Component.For<AppContext>().LifestyleScoped().Instance(context));
var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
// begin invocation
}
}
ICustomerLogic has dependency in ICustomreDal and ICustomreDal has dependency in AppContext.
So when I resolve Resolve<ICustomerLogic>() I want to be sure that ICustomreDal has the current AppContext.
ICustomerLogic and registered as singleton, and ICustomreDal registered as transient.
The first execution works fine, the second execution I get the error:
AppContext could not be registered. There is already a component with
that name. Did you want to modify the existing component instead? If
not, make sure you specify a unique name.
Isn't castle suppose to do the scope segmentation so each scope has its own dependencies?
What am I doing wrong?
Please note that we are talking about 50 executions in a second.
The BeginScope is not about registration, it is only about component resolving. It will make sure that any component that is created within the using statment, with lifestyle Scoped gets released (disposed if necessary) when the using statements end. It does not unregister components that are registered in the block. In general it is a bad idea to register your components in multiple places. Only register components at the startup of your application.
I've been struggling a lot with something similair and finally used this workaround with I was not totally happy with but if there is anyone with a better solution I would love to hear. Adapted to your situation it would look something like this:
in your registration code use:
Component.For<ICustomerLogic>().ImplementedBy<CustomerLogic>().LifestyleScoped
Component.For<AppContext >().UsingFactoryMethod(() => (AppContext)Thread.GetNamedDataSlot("context")).LifestyleTransient() // or scoped
adapt your Execute function to:
public void Execute(AppContext context)
{
using (var s = CastleContainer.Container.BeginScope())
{
Thread.SetData(Thread.GetNamedDataSlot("context"), context);
var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
Thread.SetData(Thread.GetNamedDataSlot("context"), null);
// begin invocation
}
}
Goodluck,
Marwijn.
I have a wcf service (hosted in IIS) that is setup to use sessions. It seems to work. When Application_PostAcquireRequestState is called I have a session ID.
I end up using it like this (in my Global.asax):
if (Context.Handler is IRequiresSessionState)
{
log4net.ThreadContext.Properties["sessionId"] = Session.SessionID;
}
That seems to work fine. The value is stored off into my log4net property.
But when my service operation begins (my actual WCF service code) the log4net property is null again.
Since the property is stored per thread (ThreadContext), I can only assume that this means that the session is setup on one thread then executed on another thread. Am I right?
Is there anyway to get my log4net property set on the on the correct thread (without having to remember to make the above call at the start of every single service operation)?
Yes, IIS may use multiple thread to service multiple WCF requests. See http://msdn.microsoft.com/en-us/library/cc512374.aspx for more detail.
You might consider using different instances of a logger for each WCF request.
There are multiple scenarios where WCF might change threads on you:
The Global.asx thread is not guaranteed to be used for a service call (in fact its unlikely).
If there are multiple calls during the same session, the thread may also change between calls to the same service instance.
In theory state information like this should be stored in an Operation Context object. However because log4net uses thread local storage it becomes an awkward solution.
Is there anyway to get my log4net property set on the on the correct
thread (without having to remember to make the above call at the start
of every single service operation)?
Yes. Create a custom IOperationInvoker. The best example I know of is Carlos Figueira's blog. If you apply this as a service behavior your log4net property should always be defined for the service code.
One warning: When adding to thread local storage be sure to clean up. That's why log4net.ThreadContext.Stacks[].Push() returns a IDisposable. In other words your Invoke method should look like (incomplete and untested):
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
using (log4net.ThreadContext.Stacks[key].Push(value))
{
return this.originalInvoker.Invoke(instance, inputs, out outputs);
}
}
See Carlos' blog to understand why you are calling the "originalInvoker". Note that if you want to support async operations that you need to implement additional methods.
Custom properties do not need to be strings. So you could store an instance of the following class in the global context:
public class SessionIdProperty
{
public override string ToString()
{
// error handling omitted
return Session.SessionID;
}
}
This way log4net can access the Session object directly when it logs a message. Log4net calls the ToString() method on non-string properties.
I have a piece of code that runs a Parallel.Foreach on a list of items to process. Each iteration creates a couple of objects with each object instantiating and disposing it's own instance of the Ninject IKernel. The IKernel is disposed when the object is done it's work.
That said, this code works perfectly well on my Windows 7, I7 laptop. However when I push it out to my VPS that runs Windows 2008 I get this exception. The exception doesn't happen on the same iteration, sometimes it will get through 10 iterations and throw an exception, other times it will go through hundreds of them. Obviously seems like a threading issue, but it doesn't happen anywhere but my VPS. If it matters this is being hosted in ASP.NET IIS.
System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range.
Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.Generic.List`1.RemoveAt(Int32 index)
at Ninject.KernelBase.Dispose(Boolean disposing)
Here is a snippet of the code:
//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
{
Init();
continueValidation = Validate(tran, ofr);
}
}
public class NinjectInstance : IDisposable
{
public IKernel Kernel { get; private set; }
public NinjectInstance()
{
Kernel = new StandardKernel(
new NinjectSettings() { AllowNullInjection = true },
new NinjectUnitOfWorkConfigModule());
}
public void Dispose()
{
if (Kernel != null)
{
Kernel.Dispose();
}
}
}
Edit 1
One thing is for sure, this is a thread safety issue and I should not be creating more than one instance of IKernel per application. It's a matter of understanding on how to configure the proper scopes in order to accomplish Entity Framework Context thread safety yet preserving the UoW type approach where multiple business layer classes can share the same EF context within the UoW scope within a single thread.
See http://groups.google.com/group/ninject/browse_thread/thread/574cd317d609e764
As I told you Ninject's ctor is not threadsafe atm unless you are using NOWEB! If creating/disposing the kernel so many times you will have to synchronize the access yourself! I still suggest to redesign your UoW implementation!
It seems like ninjectInstance is an instance variable. Hence, it's possible that in a parallel environment, ninjectInstance.Dispose() will be called twice (calling Kernel.Dispose() does not set the Kernel property to null) for the same instance and since Kernel.Dispose() is already been called, the method fails.
Maybe you wanted something like
using (var ninjectInstance = new NinjectInstance()) {
..
}
I'm using a 3rd party web service in my ASP.NET application. Calls to the 3rd party web service have to be synchronized, but ASP.NET is obviously multi-threaded and multiple page requests could be made that result in simultaneous calls to the 3rd party web service. Calls to the web service are encapsulated in a custom object. My thought is to store the object in an application variable and use the C# lock keyword to force synchronized use of it.
I'm nervous, because I'm new to multi threaded concepts and I've read that you shouldn't lock a public object (which my application variable effectively is). I've also read that if the locked block of code fails (which it could if the web service fails), then it could destabilize the app domain and bring down the application.
I should mention that the 3rd party web service is rarely used in my website and it's going to be rare that 2 requests to it are made at the same time.
Here's a rough code sample of how I'd make calls to the web service:
ThirdPartWebService objWebService = Application["ThirdPartWebService"] As ThirdPartWebService;
lock (objWebService)
{
objWebService.CallThatNeedsToBeSynchronized();
}
You should create a private static readonly object _lock = new object(); in the class that makes the webservice calls, and use that as a lock. Since the object is static there will only be one of them throughout all of your application, a Singleton object if you wish (http://en.wikipedia.org/wiki/Singleton_pattern)
public class MyWebServiceWrapper
{
private static readonly object _lock = new object();
public void CallWebService()
{
lock(_lock)
{
var objWebService = (ThirdPartWebService)Application["ThirdPartWebService"];
objWebService.CallThatNeedsToBeSynchronized();
}
}
}
If your class that makes the WebService call doesn't do anything else, you can also just make a lock on this (lock(this)). Just remember, that this will mean, that if you have several methods, the call to one method will block all the other methods as well, which is why you normally shouldn't lock this.
If it is vital you should only have a single call to the service at any time I recommend you write your own Windows Service. This depends on how much fault tolerance you want.
Let's say for example you make a call to the web service, but then the application pool is recycled. When a new request comes in it would be handled by a new instance of your application which could then make the call to the web service (Even if the other instance is running).
You could pass this off to a windows a service, then use a polling mechanism from the client to check if the service has finished (Client would ask IIS are you done, IIS would look for some indication from windows service that it was done). This approach will avoid locking anything in IIS, and you won't waste critical resources such as threads in your thread pool waiting on a third party service.
You should never lock on a single resource in your web application...it's just too risky.
Edit
Another option is to use the Monitor object directly:
if (System.Threading.Monitor.TryEnter(syncObj,10))
{
try
{
//CallWebService
}
finally
{
System.Threading.Monitor.Exit(syncObj);
}
}
else
{
//Tell Client they are still waiting
}
TryEnter will block until a lock is made or 10 milliseconds has passed. You could then in your timeout tell the client they need to retry. You could then have your client code decide if it should reissue the request. You could also use a semaphore or mutex (forget which one is more appropiate here). But it would assuming you have permissions to use them, give you something you can lock on at the machine level which would prevent the app recycling use case.
You can lock on a static shared object. This is a common way to use lockĀ“s in .Net. By using a static object you know it will be shared among all threads, and the lock is ensured.
As for making the app unstable if the call fails, that has to be due to the call not disposing properly. By using the "using" statement you are ensuring that dispose is called at the end of the call. Read this SO thread on why/why not you should dispose a web service regarding performance.
static readonly object _lockObj = new object();
...
lock( _lockObj )
{
ThirdPartWebService objWebService = Application["ThirdPartWebService"] As ThirdPartWebService;
objWebService.CallThatNeedsToBeSynchronized();
}
lock() will not prevent multiple call to your webservice. It will only ensure that no thread is executing code block within lock() {} at the same time.
So the the question is what does that webservice do?
1) Performs some action on third party (updates their DB with some values you supply?)
You can do as you've yourself suggested. Though I would say that if their service cannot handle simultaneous calls, then they should fix it. Thats really not your problem to worry about.
2) It queries and returns some data for your use.
In this case lock is useless unless you plan on caching the result of the call.
var cachedValue = ReadValueFromCache();
if (cachedValue != null)
return cachedValue;
lock (objWebService)
{
// yes you need to do it second time inside the lock
cachedValue = ReadValueFromCache();
if (cachedValue != null)
return cachedValue;
cachedValue = objWebService.CallThatNeedsToBeSynchronized();
SaveValueToCache(cachedValue);
}
return cachedValue;
How you implement the cache is kinda secondary. It maybe web cache object or just a static variable.