I have a windows service that starts a thread in the OnStart method.
Basically I want to be able to stop the service if something goes really wrong (like an unhandled exception).
Currently I'm using ServiceBase.Stop() but that involves having a ServiceBase instance somewhere visible to the thread, which in turn involves having my instance be declared as public static in the main program.
Is there any "better way" to stop the service? If it isn't ... is it safe to do it that way?
The easiest and, in my opinion, cleanest way is to use a public static property of the service class. The only time this won't work is if you are using the same service class to run multiple services in the same process, something that is very rare.
private static MyService m_ServiceInstance;
public static MyService ServiceInstance
{
get { return m_ServiceInstance; }
}
public MyService()
{
InitializeComponents();
//Other initialization
m_ServiceInstance = this;
}
Injecting the service instance into every method that could possibly need it is an alternative but it can quickly get messy and it has no real advantages over just using a static property.
Check out the example here on how to use the ServiceController class to start and stop services.
Alternatively, you could pass your service instance to the thread when you create it (or set it as an instance variable in the thread class, etc.) without having to make your service class static.
A short example for completeness:
ServiceController sc = new ServiceController("MyService");
sc.Stop();
Related
I am using Teststack.White to launch and interact with a GUI.
The Model is hidden behind a facade, that allows a testing mock to be injected into the GUI. The GUI successfully loads the testing mock and Teststack.White can launch the application.
How can I access my singleton using the Teststack.White.Application or means of this sort.
/*Singleton in Mock.DLL that will allow test configurations*/
class Hook
{
public Hook SingleHook { get; private set; } = new Hook();
private Hook() { }
}
/*Loader in Nunit so far*/
private Application apploader()
{
ProcessStartInfo info = new ProcessStartInfo(#"C:\MyGUI\MYWPFGUI.exe");
info.WorkingDirectory = (#"C:\MyGUI\");
TestStack.White.Application app = Application.Launch(info);
return app;
}
I am currently investigating using AppDomains but since this Application is running in its won process i can not see how I would do that.
I need to get a hold of Singleton in order to setup and evaluate my tests.
I think the only way to do that is using some sort of inter process communication.
There are many example on google on here on SO here or here
You need to use reflection, first step is to Load the assembly that holds the Hook class by using Assembly.Load or Assembly.LoadFrom , then you use Assembly.CreateInstance or Activator.CreateInstance or AppDomain.CreateInstanceAndUnwrap methods and pass the Hook class type, now you cannot create the singleton from outside and then call CreateInstance to create it since it has private ctor, otherwise you need to use other means like GetMethod and Invoke from the Hook Singleton type to access its methods which is too much hassle.
However, i would suggest you create the class as normal class and hold a singleton instance in Test application, so make sure to mark your Hook class as public class with public constructor and in the Test project create a public static property/variable to hold the created class with reflection and then you can access the Singleton Hook class anywhere in the Test application by just calling the static property.
I have a class like so
public class FileLogger
{
public FileLogger(string typeOfLog)
{
//implementation
}
public void LogError(string err)
{
//implementation
}
public void LogMessage(string err)
{
//implementation
}
}
Since this is a logging class for an application to log its output to a file, one would have expected it to be a static class. However as you can see it is not. It is however used in the application like this:
public class BugetApplication
{
private static FileLogger logger;
//constructor
public BugetApplicationClass()
{
logger = new FileLogger("some-constructor-parameter");
}
//a method that uses the FileLogger class for logging
public string Classify()
{
try
{
//start multiple threads for classification
Classification clsf = new Classification();
clsf.handleEvent += clsf_handleEvent;
clsf.Classify();
}
catch (Exception exp)
{
logger.LogError(exp.Message);
}
}
private static void clsf_handleEvent(string errString)
{
if(errString.Contains("error"))
{
logger.LogError(errString);
}
}
}
Multiple threads are started by the BugetApplication class's classify method. Any errors in that class fire an event which is handled in the BugetApplication class's clsf_handleEvent method. So multiple threads could each fire their own event. Would creating the instance variable as a static variable in the BugetApplication class have any effect here or would keeping it non static have the same effect? I don't want any one thread to overwrite the error message of another thread.
Edit
Just to clear things out, the BugetApplication class which will be created only once has a static variable 'static FileLogger logger; ' it creates an instance once in its constructor, passing in some values to the constructor of the FileLogger class. In the BugetApplication class, there is a method which calls the Classification class's classify method. The Classify method starts the various threads and on any error fires an event which is handled back in the BugetApplication class so this clsf_handleEvent method can have multiple calls on it.
Why do you think it would overwrite the error message of another thread? The logger should just append the messages, so there shouldn't be any overwriting (depends how you handle the logging though). There is a potential problem however - depending on your logging function you might be blocking access to the file. Because the method works on an external file, you should probably use lock in the function.
It really doesn't matter if the class is static or not, the problem is concurrent access to external resources which needs to be synchronized for multiple threads to become thread-safe.
lock documentation on msdn
It really depends on the actual implementation of the logger.
Static classes are now frowned upon as they make unit testing more difficult. Many facilities which conventionally were implemented as static or singleton (loggers, e-mailers, etc.) now provide unit test/IoC friendly alternatives (e.g. a factory and an interface or virtual class).
The design of these facilities is usually a front end class which the client application uses to interact and an asynchronous back end which takes care of the synchronization and actual logging (or emailing, or whatever).
The crux is whether the front ends are multi-threaded or not.
If they are not; you should create a new one per thread. In this case the logger would probably have to be a local variable or parameter of the method using it.
Usually, however, they are multi-threaded and re-entrant, as all they do is pass along the log message to the back-end and have no state of their own. In this case they can be saved as a static variable or application wide singleton, but it is better to instantiate them in an IoC container as singleton and inject it to the classes using them. Doing so makes writing unit tests with mock loggers a lot easier.
I am a beginner in c# and need a help in sorting out the following problem.
In my program, I want to start a service but only after the a method is completed. For example,
{
// A method which copies file
A();
// A service that uses the copied files in function A()
ServiceController service = new ServiceController("ServiceName");
service.Start();
}
Problem is that the service has already started, but the the method A() has not finished copying yet.
Any idea or help is most welcomed!
You can do it with ServiceController class.
You can use the ServiceController class to connect to and control the
behavior of existing services. When you create an instance of the
ServiceController class, you set its properties so it interacts with a
specific Windows service. You can then use the class to start, stop,
and otherwise manipulate the service.
Couple of suggestions
You can invoke method A() synchronously from main method so that succeeding service start() code will only be executed after A() completes.
If there is no restrictions and if you have access to code where A() resides, Why don't you move the windows service start() logic to your method A(), probably you can place the logic at the end of the method A()
private void SomeMethod()
{
A();
ServiceController controller = new ServiceController("WindowsServiceName");
controller.Start();
}
I have a method which is invoked in class A and it is defined in class B:
class B{
[STAThread]
public static void ScanForAxisCameras() {
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
Application.Run();//if not invoked everything above does not start
}
}
class A{ ...before invoking..... B.ScanForAxisCameras(); ....after invoking....}
The code in class B "starts"/works only if I invoke Application.Run(). But it causes that all the code in class A ....after invoking.... method does not work. How to handle it so it will not freeze the application?
Edit: the class A is class MainWindow.xaml.cs. It is WPF application.
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
createGUI();
}
private void createGUI() {
LocalNetworkScanner.ScanForAxisCameras();//when there is no Application.Run() ScanForAxisCameras() does not work.
}
}
The WPF UI thread on which you call ScanForAxisCameras() already has a message loop. I believe the problem with your code is that all objects you create inside ScanForAxisCameras have the local scope:
public static void ScanForAxisCameras() {
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
Application.Run();//if not invoked everything above does not start
}
Without Application.Run(), your objects (service, eventManager, browse) may be getting destroyed and finalized as soon as ScanForAxisCameras finishes. So, the events you're looking for (like ServiceFound) may not even have a chance to get fired.
If you call Application.Run(), then ScanForAxisCameras doesn't exit (at least not until Application.Run() itself exits). That keeps your objects alive and functional.
Try refactoring your code to keep the references to these objects in member fields of your class (or in static variables, FWIW). I believe that should fix the problem.
[EDITED] On a side note, the [STAThread] attribute doesn't make sense in that context (unless you use ScanForAxisCameras as an entry point for a new thread - apparently, that's not the case here).
You can introduce a new Run()-method in your App in the App.xaml.cs file.
Here you can perform custom actions before the application itself gets initialized.
Further information here.
public partial class App : Application
{
public new void Run()
{
// Do your stuff here
B.DoStuff();
// Call the base method
base.Run();
}
}
Application.Run starts the message loop for that particular thread, if there is no message loop then there is no notification for your objects to know they have to do something.
The code in class B "starts"/works only if I invoke Application.Run(). But it causes that all the code in class A ....after invoking.... method does not work.
Run is a blocking call therefore any code after that call is not reachable until the application is closing down i.e. when you exit the message loop.
How to handle it so it will not freeze the application?
In short, you can't. Run will always block so any code you need to run as part of your application startup will have to happen before the call.
After your edit to mention that this is a WPF application then Application.Run as a static method is not the right way to go here. If you need to run initialization when your application starts then you can do what has already been suggested and override the Run method of the Application class, or alternatively (maybe more appropriately) you can hook into the OnStartup event e.g.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// code before startup
base.OnStartup(e);
// code after startup
}
}
It seems as though in this situation you would need to add Application.Run() in a different class. Run() accepts nothing, ApplicationContext, Form. This controls the lifetime of the application and should be called before class A, unless class A is the entry point.
See http://msdn.microsoft.com/en-us/library/ms157900.aspx for details.
A Windows Forms application starts when the Main method is called. You can implement initialization procedures on the Main function. However, to initialize a Windows Forms application fully and start it routing Windows Forms events, you need to invoke Application.Run.
you can read about Application here
I am enjoying creating and hosting WCF services.
Up until now I can create services defining contracts for the service and data (interfaces) and defining hosts and configuration options to reach them (endpoint specifications).
Well, consider this piece of code defining a service and using it (no mention for endpoints that are defined in app.config not shown here):
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
using (ServiceHost host = new ServiceHost(typeof(MyService))) {
host.Open();
...
host.Close();
}
}
}
Well, this structure is good when creating something that could be called a Standalone service.
What if I needed my service to use objects of a greater application.
For example I need a service that does something basing on a certain collection defined somewhere in my program (which is hosting the service). The service must look into this collection and search and return a particular element.
The list I am talking about is a list managed by the program and edited and modified by it.
I have the following questions:
1) How can I build a service able to handle this list?
I know that a possible option is using the overloaded ServiceHost constructor accepting an Object instead of a Type service.
So I could pass my list there. Is it good?
[ServiceContract]
public interface IMyService {
[OperationContract]
string Operation1(int param1);
[OperationContract]
string Operation2(int param2);
}
public class MyService : IMyService {
private List<> myinternallist;
public MyService(List<> mylist) {
// Constructing the service passing the list
}
public string Operation1(int param1) { ... }
public string Operation2(int param2) { ... }
}
public class Program {
public static void Main(stirng[] args) {
List<> thelist;
...
MyService S = new MyService(thelist)
using (ServiceHost host = new ServiceHost(S)) {
host.Open();
...
host.Close();
// Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface)
}
}
}
This example should clarify.
Is it the good way of doing? Am I doing right?
2) How to handle conflicts on this shared resource between my service and my application?
When my application runs, hosting the service, my application can insert items in the list and delete them, the same can do the service too. Do I need a mutex? how to handle this?
Please note that the concurrency issue concerns two actors: the main application and the service. It is true that the service is singleton but the application acts on the list!!!
I assume that the service is called by an external entity, when this happens the application still runs right? Is there concurrency in this case???
Thankyou
Regarding point 2, you can use Concurrent Collections to manage most of the thread safety required.
I'm not sure what you mean by point 1. It sounds like you're describing basic polymorphism, but perhaps you could clarify with an example please?
EDIT: In response to comments you've made to Sixto's answer, consider using WCF's sessions. From what you've described it sounds to me like the WCF service should be sat on a seperate host application. The application you are using currently should have a service reference to the service, and using sessions would be able to call an operation mimicking your requirement for instantiating the service with a list defined by the current client application.
Combine this with my comment on exposing operations that allow interaction with this list, and you'll be able to run multiple client machines, working on session stored Lists?
Hope that's explained well enough.
Adding the constructor to MyService for passing the list certainly will work as you'd expect. Like I said in my comment to the question however, the ServiceHost will only ever contain a single instance of the MyService class so the list will not be shared because only one service instance will consume it.
I would look at a dependency injector (DI) container for WCF to do what you are trying do. Let the DI container provide the singleton list instance to your services. Also #Smudge202 is absolutely correct that using the Concurrent Collection functionality is what you need to implement the list.
UPDATE based on the comments thread:
The DI approach would works by getting all of an object's dependencies from the DI container instead of creating them manually in code. You register all the types that will be provided by the container as part of the application start up. When the application (or WCF) needs a new object instance it requests it from the container instead of "newing" it up. The Castle Windsor WCF integration library for example implements all the wiring needed to provide WCF a service instance from the container. This posts explains the details of how to use the Microsoft Unity DI container with WCF if you want to roll your own WCF integration.
The shared list referenced in this question would be registered in the container as an already instantiated object from your application. When a WCF service instance is spun up from the DI container, all the constructor parameters will be provided including a reference to the shared list. There is a lot of information out there on dependency injection and inversion of control but this Martin Fowler article is a good place to start.