Windows Service Implementing IDisposable - Is it bad practice? - windows

I've come across this code:
public class ServiceLauncher2 : ServiceBase, IDisposable
And then this:
/// <summary>
/// Disposes the controllers
/// </summary>
// This is declared new as opposed to override because the base class has to be able to
// call its own Dispose(bool) method and not this one. We could just as easily name
// this method something different, but keeping it Dispose is just as valid.
public new void Dispose()
{
foreach (var mgr in _threadManagers)
mgr.Dispose();
base.Dispose();
}
I've never seen this in a Windows Service implementation before. Usually just OnStop/OnStart is overridden. Is this bad practice?

Let's count the ways this is bad practice:
The new keyword is grating, it tells the compiler to shut up about a potential problem in the code. A real one, the code that uses this class can easily end up calling ServiceBase.Dispose() instead. ServiceBase implements the disposable pattern, the correct way to do it is to override the protected Dispose(bool) method
The Dispose() method leaves a _threadManagers collection object behind that contains nothing but dead objects. Which makes the collection dead as a doornail as well, iterating it afterwards is meaningless. It should have been emptied
The only time this Dispose() method can be called is at service termination. Can't do it in OnStop(), it also disposed the ServiceBase. Disposing "controllers" a microsecond before the finalizers run and the process terminates makes no sense. Dispose() should only ever be used to allow unmanaged resources to be de-allocated early. There is no early when the process stops a millisecond later
This code makes no sense. Don't use it.

It does look non-standard but it is legit. So I wouldn't necessarily call it bad practice, though the fact that it introduces confusion makes it bad practice?
Does this run only as a service or is there console mode? (Console app would not get OnStop called.) Or is there some other (custom) way to stop this service process?
Ammending from my own earlier question of:
I'm not sure why new instead of override, especially since
base.Dispose() is being called.
Reason:
'SomeClass.Dispose()': cannot override inherited member
'System.ComponentModel.Component.Dispose()' because it is not marked
virtual, abstract, or override
In other words, the implementaion of ServiceBase.Dispose is not overridable.

Just to add to the already perfect answers by Hans and Paul: declaring ServiceLauncher2 as IDisposable is redundant, as ServiceBase is a Component which in turn is already IDisposable

Related

Are there penalties for just using the new keyword instead of creating a class variable before calling the class method?

Example
(1)
var classVar = new class();
classVar.Method();
(2)
new class().Method();
I like the second way, less wordy.
Is there a performance difference?
Is it considered bad coding practice?
If your Method() doesn't use anything from that class, why is it defined there? You could use namespace instead.
The only difference between your (1) and (2) is that the class instance is destructed immediately in (2).
in your case Method seems to be static (ie there is no useful data stored inside the instance of 'class' (note I am ignoring all the invalid / not recommended name issues). Assuming this is c# but all languages have the same ideas, you would go
public class class{ // ugh
public void static Method(){
Console.WriteLine("I am Method");
}
}
now you can go
class.Method();
so the code is neatly filed away inside 'class' but you dont have to pay any overhead.
If you really need to instantiate 'class' then presumably you need to do more than just call one method on it. In which case
new class().Method();
makes no sense, since you call create it, call a method and destroy it.
Really a more concrete example is needed

Xamarin Async Constructor

For my application I need to fetch some data asynchronously and do some initialization for each page. Unfortunately, a constructor does not allow me to make asynchronous calls. I followed this article and put all of my code into the OnAppearing method. However, since then I ran into multiple issues since each platform handles the event a little bit differently. For example, I have pages where you can take pictures, on iOS the OnAppearing is called again every time after the camera is closed while Android doesn't. It doesn't seem like a reliable method for my needs, which is also described here:
Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.
I am searching for a method/way where I can perform my own initialization. The constructor would be perfect for that but I cannot perform anything asynchronously in there. Please do not provide me with any work arounds, I am searching for a solution that is the "recommended" way or maybe someone with a lot of experience can tell me what they are doing. (I also don't want to .Wait() or .Result as it will lock my app)
You can use Stephen Cleary's excellent NotifyTaskCompletion class.
You can read more how it works and what to do/don't in these cases in Microsoft's excellent Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding. The highlights of this topics are:
Let’s walk through the core method
NotifyTaskCompletion.WatchTaskAsync. This method takes a task
representing the asynchronous operation, and (asynchronously) waits
for it to complete. Note that the await does not use
ConfigureAwait(false); I want to return to the UI context before
raising the PropertyChanged notifications. This method violates a
common coding guideline here: It has an empty general catch clause. In
this case, though, that’s exactly what I want. I don’t want to
propagate exceptions directly back to the main UI loop; I want to
capture any exceptions and set properties so that the error handling
is done via data binding. When the task completes, the type raises
PropertyChanged notifications for all the appropriate properties.
A sample usage of it:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
Here, the demo is about binding the returned asynchronous value to some bindable property, but of course you can you is without any return value (for simple data loading).
This may be too simple to say, but you CAN run asynchronous tasks in the constructor. Just wrap it in an anonymous Task.
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
Be careful when doing this though as you can get into resource conflict issues if you accidentally open the page twice.
Another thing I like to do is use an _isInit flag, which indicates a first time use, and then never again.

GetFunctionPointerForDelegate and pin pointer

Hi this is in regard to some code given in C++ CLI i action which i have trouble understanding.The code is given below
delegate bool EnumWindowsDelegateProc(
IntPtr hwnd,IntPtr lParam);
ref class WindowEnumerator
{
private:
EnumWindowsDelegateProc^ _WindowFound;
public:
WindowEnumerator(EnumWindowsDelegateProc^ handler)
{
_WindowFound = handler;
}
void Init()
{
pin_ptr<EnumWindowsDelegateProc^> tmp = &_WindowFound;
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
}
};
In the above code _WindowFound has been pinned so GC wont moove it.The Question is
Isn't tmp only valid inside Int() thus _WindowFound pinned only
during call to Int() ?
If thats the case Isn't there a chance the delegate location in
memory might change at the time EnumWindows calls it as a function
pointer?
A pin_ptr<> automatically unpins, RAII-style, when code execution leaves the block that it is declared it. So it will be pinned for the entire body of the Init() method in your code. So your 2 bullet does not apply.
It is notable that the code is in not infact correct. It works, but by accident. Marshal.GetFunctionPointerForDelegate() invokes the stub compiler to auto-generate the native code that's needed to allow the native code to invoke the delegate target. The lifetime of that stub is controlled by the lifetime of the delegate object. In other words, as soon as the delegate object gets garbage collected, the stub will be destroyed as well.
Pinning the delegate object does not in any way affect the stub. It is already unmovable, the GC never moves code. It works by accident because pinning an object requires creating an extra GC handle for the object (GCHandle::Alloc), enough to prevent premature collection.
It doesn't make an enormous difference in this kind of code, EnumWindows() is slow anyway. Not necessarily the case when you call other native code that requires a callback, avoiding pinning should always be a goal in general. All you have to do is let the jitter see a reference to the delegate object beyond the code where it can still be used, like this:
void Init() {
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
GC::KeepAlive(_WindowFound);
}
Very efficient, GC::KeepAlive() doesn't generate any code, it just tells the jitter to extend the lifetime of the _WIndowFound reference so it can't be collected while EnumWindows() is executing. Even that is overkill in this specific case since somebody is going to have a reference to the WindowEnumerator object in order to retrieve _WindowFound, but better safe than sorry.

Ninject and OnePerRequestModule

I have recently tried out Ninject with the Ninject.Web.Mvc extension, and I've noticed something peculiar and, while not breaking, confusing.
In the NinjectHttpApplication abstract class, there is a constructor defined as follows..
/// <summary>
/// Initializes a new instance of the <see cref="NinjectHttpApplication"/> class.
/// </summary>
protected NinjectHttpApplication()
{
this.onePerRequestModule = new OnePerRequestModule();
this.onePerRequestModule.Init(this);
}
I have placed a debugger breakpoint here, and this gets called a few times. I cannot find any real documentation on it. In the implementation code, there is this line that catches my eye.
if (kernel.Settings.Get("ReleaseScopeAtRequestEnd", true))
{
OnePerRequestModule.StartManaging(kernel);
}
My questions are as follows...
What is OnePerRequestModule
Why is this constructor being called multiple times?
What is the purpose of this StartManaging method, if the constructor is called multiple times?
The OnePerRequestModule removes InRequestScope()d objects from the Kernel's Cache upon completion of each HTTP Request.
The NinjectHttpApplication ctor is called multiple time because IIS creates several of them. One NinjectHttpApplication can only handle one request at a time. So IIS generates (at least) one instance per thread.
StartManaging tells all OnePerRequestModules that they shall release the InRequestScoped objects from the specified Kernel after the Request has Ended.

COM object that has been separated from its underlying RCW cannot be used

I am trying to use the OpcRcw.da.dll. If I interop this dll inside a test console project everything works, but if I build dll project to do my interop gymnastic and ref my library into my console project I am getting this error:
COM object that has been separated from its underlying RCW cannot be used.
What need to be done to a class lib project to not kill the RCW ref?
This can happen for a few reasons, the big ones I know of are below.
Event Handlers Without Strong References to the Delegate
A caller subscribes to an event on the com object without keeping a strong reference to the callback delegate. Here is an example of how to do this correctly and how to not do it:
The reason for this is a strong reference needs to be kept to the delegate, if it goes out of scope, the wrapper will release the reference count for the interface and bad things will happen.
public class SomeClass
{
private Interop.ComObjectWrapper comObject;
private event ComEventHandler comEventHandler;
public SomeClass()
{
comObject = new Interop.ComObjectWrapper();
// NO - BAD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// YES - GOOD!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
}
public void EventCallback()
{
// DO WORK
}
}
Calls to a disposed Runtime Callable Wrapper
The wrapper has been disposed and calls are being made after it has been disposed. A common way this can happen is if a control is using an activex control or COM object and the controls Dispose() is called out of order.
A form gets Close() called.
System.Windows.Forms.Close() will call Dispose()
Your forms virtual Dispose() will be called which hopefully calls base.Dispose() somewhere. Systems.Windows.Forms.Dispose() will release all COM objects and event syncs on the form, even from child controls.
If the control that owns a com object is explicitly disposed after base.Dispose() and if it calls any methods on it's COM object, these will now fail and you will get the error “COM object that has been separated from its underlying RCW cannot be used”.
Debugging Steps
A good way to debug this issue is to do the following:
Write a class that inherits from the Interop class (otherwise known as the runtime callable wrapper or RCW).
Override DetachEventSink
Override Dispose
Call your new class instead of calling the interop class directly
Add breakpoint to DetachEventSink and Dispose
See who is calling these methods out of order
One other thing
This isn't related to this issue but while we are on the topic, unless you know otherwise, always remember to check that the thread your COM objects are being used from are marked STA. You can do this by breaking in the debugger and checking the value returned from:
Thread.CurrentThread.GetApartmentState();
It's somewhat hard to tell what your actual application is doing, but it sounds like you may be instantiating the COM object and then attempting to access it from another thread, perhaps in a Timer.Elapsed event. If your application is multithreaded, you need to instantiate the COM object within each thread you will be using it in.

Resources