I have a self hosted named pipes (not using http) wcf hosted in a class library. I am able to start the WCF by using the following method in the class library:
ServiceHost serviceHost;
public void startService()
{
// Create the service host
...
// Open Service Host
serviceHost.Open();
}
And then from a winforms test program running the following from a button click:
MyClassLib.MySvc testSvc;
private void button2_Click(object sender, EventArgs e)
{
testSvc = new MyClassLib.MySvc();
testSvc.startService();
}
This does correctly start the WCF running in the class library.
But this requires the winforms that is referencing the class library to call startService method.
What I would like is just to be able to start the service as soon as a reference to the class library that will be running the WCF is done.
I have attempted to add the following in the class library service's constructor:
public MySvc()
{
startService();
}
And then instantiate from the winforms:
MyClassLib.MySvc testSvc;
private void button2_Click(object sender, EventArgs e)
{
testSvc = new MyClassLib.MySvc();
//testSvc.startService(); //No need to call this
}
If I debug the code, I can see that in fact it does break at this point:
public MySvc()
{
startService(); // It does run this but service does not start
}
But this does not run the service. Any help would be appreciated.
Note #1: I believe its some type of timing issue where it does not let you start the service during the constructor method but not sure of that.
Problem resolved and yes my assumption that it was a timing issue (See Note# 1 above) was correct!
To replicate, change this:
public MySvc()
{
startService(); // It does run this but service does not start
}
To this and problem solved:
public void delayStartService()
{
Task.Delay(1000).ContinueWith(t => startService());
}
public MySvc()
{
delayStartService();
}
Related
I am using SignalR in my web project. I first created the hub as a console application, to allow for easier debugging, it worked flawlessly. I recently tried to switch SignalR over to a windows service and I keep getting the error Uncaught TypeError: Cannot read property 'client' of undefined when trying to reference client on any function
$.connection.hub.url = "https://localhost:8080/signalr";
var dc = $.connection.deviceController
dc.client.anything = ...
This is odd, because I can navigate to https://localhost:8080/signalr/hubs manually without issue. My service app is almost an exact replica of the console app, simply just starting the hubs in the OnStart() method.
StartUp.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
OnStart in service
protected override void OnStart(string[] args)
{
Status("Service starting...");
const string url = "https://*:8080";
try
{
WebApp.Start<Startup>(url);
}
catch (Exception e)
{
Status(e.ToString());
throw;
}
}
Any insight here?
EDIT: I may also point out that deviceController hub is in a referenced class library, but I didn't think that would be an issue since it is referenced properly.
I m a bit new here . I am trying to learn window service from microsoft tutorial :
http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx
I installed and run it perfectly ..event logs are working Fine ...Now I am trying access One function in another c# project (named ASMSFetch) which has reference to the service project ...
This is Service .cs file code
public partial class MyNewService : ServiceBase
{
public MyNewService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ASMSFetch.Program.UpdateSMS();
}
}
and ASMSFetch Project Program.cs
public class Program
{
static void Main(string[] args)
{
UpdateSMS();
}
public static void UpdateSMS()
{
Console.WriteLine("UpdateSMS started");
Console.ReadLine();
}
But that "UpdateSMS started" messege doesnot appear when I install and run the service from computer management -> service section ..
I tried to search it .but couldnt able to find reasonable .
Any suggestion would be helpful ...
See here...
http://msdn.microsoft.com/en-us/library/76477d2t(v=vs.110).aspx
Under item #4 - you need to call your service. If the above is all your code, then you're missing that and nothing is actually starting the service. When the OS starts your service, all it does is call the Main() method, just like any other EXE.
You need to add a line like this:
System.ServiceProcess.ServiceBase.Run(new MyNewService());
My WPF application has an App class, and it inherits from System.Windows.Application.
Inside this class I have my exception handling that handles DispatcherUnhandledException, so any un handled exceptions may be caught and be presented to the user.
To test this I start my test with
//Arrange
app = new App();
and then I continue with the rest of the test setup.
Later on in my test I run this code:
//Act
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, new MyDlg(RaiseArgumentNullException));
This triggers ApplicationStartup to be executed in the App class.
When my next test starts it also creates a new App class, and also uses the CurrentDispatcher.Invoke to create another type of exception. However, the first Application seems to be running.
If I run my two tests one by one, they work just fine. But if I run them in sequence the second one fails.
Does anyone have any idea of how to properly shut down the Application after the test is done?
I have tried the following ways to shut the application down, but it doesn't work.
static void CloseApp()
{
Application.Current.Shutdown();
}
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Send, new MyDlg(CloseApp));
app.Shutdown();
Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Send);
This is how my code looks like:
delegate void MyDlg();
static void RaiseArgumentNullException()
{
throw new ArgumentNullException();
}
[Test]
public void MyTest()
{
//Arrange
app = new App();
//...
//Act
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, new MyDlg(RaiseArgumentNullException));
//Assert....
//Tear Down
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Send, new MyDlg(CloseApp));
app.Shutdown();
Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Send);
}
And this is my App class:
public partial class App : Application
{
public App()
{
Startup += ApplicationStartup;
DispatcherUnhandledException += AppDispatcherUnhandledException;
Bootstrapper.InitializeIoc();
}
private void ApplicationStartup(object sender, StartupEventArgs e)
{
//Do startup stuff
}
void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
HandleException(e.Exception);
e.Handled = true;
}
//....
}
The Application class does not allow more than one instance of Application (or any subclass) to be created per AppDomain. This is regardless of whether the Application is still running or not. From MSDN:
Application implements the singleton pattern to provide shared access
to its window, property, and resource scope services. Consequently,
only one instance of the Application class can be created per
AppDomain.
To work around this, you could create an AppDomain in each of your tests.
I have a custom HttpModule implemented for a site I am working on. It is designed to perform an action on the PreSendRequestContent event. When I run the debugger and built in Visual Studio Server it runs without any problems. BUt when I publish it to the Live Server it doesn't. I am using a Classic Mode configuration of IIS meaning that I should only have to add the module to the web.config file. Am I missing something?
namespace SmartBilling
{
public class HttpModule : IHttpModule
{
public HttpModule()
{
}
public void Init(HttpApplication httpApplication)
{
// Register our event handler with Application object.
httpApplication.PreSendRequestContent += new EventHandler(httpApplication_PreSendRequestContent);
}
void httpApplication_PreSendRequestContent(object sender, EventArgs e)
{
// Do stuff
}
public void Dispose()
{
// Left blank because we dont have to do anything.
}
}
}
I'll start by saying I'm not a .NET developer, but have been thrown into a project where I need to use MSMQ so a classic ASP web application can send messages to a C# Windows Service that handles the processing. I have experience integrating other message queues with other languages, but like I mentioned, I don't have much experience with .NET and Windows development so some guidance would be much appreciated.
Here are my questions...
Could someone provide some basic C# code that listens to an existing MSMQ queue and responds to the new message by doing something simple like writing the current timestamp to a log file or sending an email?
How do I package this code up in Visual Studio .NET to create and install a Windows Service? (What type of project should it be, etc. I'm using Visual C# 2010 Express.)
Finally, I'm not sure which version and/or implementation of MSMQ I need to be using for my requirements with classic ASP. I think the COM version is what I need, but I've also read about a new WCF version, as well as differences between 3.0 and 4.0. Could someone please give me direction on which version I should be using?
Many thanks!
You can wait for a message on a given queue using the following code (You want to use the private queue named SomeQueue on your computer, named ComputerName => QueueName = #"ComputerName\private$\SomeQueue")
public void AsyncWatchQueue(object encapsulatedQueueName)
{
Message newMessage;
MessageQueue queue;
string queueName = encapsulatedQueueName as string;
if (queueName == null)
return;
try
{
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName);
else
{
queue = new MessageQueue(queueName);
if (queue.CanRead)
newMessage = queue.Receive();
}
HandleNewMessage(newMessage); // Do something with the message
}
// This exception is raised when the Abort method
// (in the thread's instance) is called
catch (ThreadAbortException e)
{
//Do thread shutdown
}
finally
{
queue.Dispose();
}
}
Note: the Receove method will block untill a message is received at which point it'll remove the message from the queue and return it.
edit: added code for the implementation of the multithreaded portion (and renamed the above method signature)
Thread Creation Code:
public Thread AddWatchingThread(string QueueName)
{
Thread Watcher =
new Thread(new ParameterizedThreadStart(AsyncWatchQueue));
Watcher.Start(QueueName);
// The thread instance is used to manipulate (or shutdown the thread)
return Watcher;
}
I'll just note, that this is untested cod, it's just an quick example
As far as I know, Visual Studio Express does not have a project template for a service. That does not mean you cannot write a windows service with VSE, just that you will not have a template to get you started.
To create a service you can just create a normal Console application. Create the service class which will be responsible for the actual service implementation. It will look something like this
using System.ServiceProcess;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
}
Then the Service startup code can go into the Main function of your service.
using System.ServiceProcess;
namespace WindowsService1
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
That should give you the basic framework for your service. The other thing you will need is to add an installer for the service so that it can be installed as a service. The following should get you started, note I have note tested this.
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;
namespace WindowsService1
{
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller serviceProcessInstaller1;
private ServiceInstaller serviceInstaller1;
public ProjectInstaller()
{
this.serviceProcessInstaller1 = new ServiceProcessInstaller();
this.serviceInstaller1 = new ServiceInstaller();
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
this.serviceInstaller1.ServiceName = "Service1";
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
}
}
Given the above, you should have enough to search around or ask for more details around the service creation. As for the MSMQ listener, you can use the following MSDN article as a starting point
http://msdn.microsoft.com/en-us/library/ms978425.aspx