QueueClient.OnMessage throws StackOverflowException during Worker Role Start up - c#

I am trying to deploy my first Azure worker role and I have been running into this error when Run() method is called during service start up.
An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module.
I've tried to remote debug my code and the error is thrown at this line. MyPublisher is similar to MyQueue but it wraps Topic instead of a Queue. Any idea why QueueClient.OnMessage would cause StackOverflow?
Client.OnMessage(messageHandler, options);
Here is the partial code. My Apology if it is not formatted correctly (will try to format) or anything is missing in code.
public class MyQueue
{
String QueueName;
public QueueClient Client { get; protected set; }
public MyQueue(String queueName)
{
Trace.WriteLine($"Creating service Queue with name : {queueName} ");
QueueName = queueName;
}
public void EstableshConnection(string connectionString = null)
{
Trace.WriteLine($"Establishing connection with service Queue : {QueueName} ");
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
connectionString = connectionString ?? CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
if (!namespaceManager.QueueExists(QueueName))
namespaceManager.CreateQueue(QueueName);
Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
}
public void Send(BrokeredMessage message)
{
Trace.WriteLine($"Sending brokered message to queue : {QueueName} ");
if (Client != null && !Client.IsClosed)
Client.Send(message);
}
public void OnMessage(Action<BrokeredMessage> messageHandler)
{
Trace.WriteLine($"OnMessage handler: Queue Name : {QueueName} ");
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = true; // Indicates if the message-pump should call complete on messages after the callback has completed processing.
options.MaxConcurrentCalls = 1; // Indicates the maximum number of concurrent calls to the callback the pump should initiate
options.ExceptionReceived += LogErrors; // Allows users to get notified of any errors encountered by the message pump
//=====================StackOverFlowException on Client.OnMessage======
if (Client != null && !Client.IsClosed)
Client.OnMessage(messageHandler, options); //This is where I get StackOverflowException Error.
}
private void LogErrors(object sender, ExceptionReceivedEventArgs e)
{
if (e.Exception != null)
Trace.WriteLine("Queue client processing error: " + e.Exception.Message);
}
public void Disconnect()
{
Trace.WriteLine($"closing queue {QueueName}");
Client.Close();
}
}
Here is my workerrole implementation.
public class MyWorkerRole : RoleEntryPoint
{
#region Variables
ManualResetEvent CompletedEvent = new ManualResetEvent(false);
MyQueue RequestQueue; //for Request
MyPublisher ResponseTopicClient; //ReponseTopic to notify Subscriber when processing is completed
Public MyWorkerRole()
{
RequestQueue = new MyQueue("JobRequestQueue");
ResponseTopicClient = new MyPublisher("JobCompletedTopic");
}
public override bool OnStart()
{
try
{
RequestQueue.EstableshConnection();
ResponseTopicClient.EstableshConnection();
}
catch (Exception ex)
{
Trace.TraceWarning($"Trace: starting service failed. Error {ex.Message} ");
}
return base.OnStart();
}
public override void OnStop()
{
try
{
RequestQueue.Disconnect();
ResponseTopicClient.Disconnect();
CompletedEvent.Set();
}
catch (Exception ex)
{
Trace.TraceWarning($"Trace: stopping service failed with error. {ex.Message} ");
}
base.OnStop();
}
public override void Run()
{
try
{
Trace.WriteLine("Trace: Starting Message Processing");
//var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));
RequestQueue.OnMessage((receivedMessage) =>
{
try
{
Guid resultGuid = (Guid)receivedMessage.Properties["CorrelationGuid"];
Trace.TraceWarning($"Trace: processing message with GUID {resultGuid}");
var messageToSend = JobProcessor.ProcessRequest(receivedMessage);
if (messageToSend == null)
{
Trace.TraceError("Trace: > Broken message!");
receivedMessage.Abandon();
return;
}
ResponseTopicClient.Send(messageToSend);
receivedMessage.Complete();
}
catch (Exception ex)
{
Trace.TraceError("Trace: Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
Logger.Error("Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
}
});
CompletedEvent.WaitOne();
}
catch (Exception ex)
{
Trace.TraceError("Trace: Run exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
}
finally
{
CompletedEvent.Set();
}
}
}

When your worker starts, it calls the Run method and in your code, you have :
//var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));
RequestQueue.OnMessage((receivedMessage) =>
So, The code doesn't wait for a new message because the first line is commented and it calls the OnMessage method which recursibly calls itself again and again till the StackOverflowException gets fired
In all cases, you need to change the implementation because StackOverflowException will happen anyway when a new message is received

Figured it out. So, the issue was not with the code. Following error was reported in WADWindowsEventLogsTable under my storage account.
Faulting application name: WaWorkerHost.exe, version: 2.7.1198.768, time stamp: 0x57159090
Faulting module name: Microsoft.IntelliTrace.Profiler.SC.dll, version: 15.0.27128.1, time stamp: 0x5a1e2eb9
Exception code: 0xc00000fd
Fault offset: 0x000000000008ae7b
Faulting process id: 0xcf4
Faulting application start time: 0x01d3b75ed89dc2f9
Faulting application path: F:\base\x64\WaWorkerHost.exe
Faulting module path: F:\plugins\IntelliTrace\Runtime\x64\Microsoft.IntelliTrace.Profiler.SC.dll
This gave me a hint about disabling the IntelliTrace and it worked just fine. Here is how you can disable while publishing a package through VS 2017.
1.) Right click on your worker role project and select publish from menu
2.) In Settings page->Advanced Settings, uncheck "Enable IntelliTrace" option.

Related

Windows Service runs but stops processing after two days

I've seen a fair few posts regarding this issue but non that seem to fit my criteria.
Having said that, this is the first one that I've built that "needs" to perform a tremendous amount of logic. All works great for a couple days but after that logic stops working with no log in the event viewer nor firing of an email (exceptions).
I'm wondering if my logic is not correct... Looking for advice and pointers.
public partial class QuayService : ServiceBase
{
private System.Timers.Timer m_mainTimer;
private bool m_timerTaskSuccess;
private Email _email;
public QuayService()
{
InitializeComponent();
_email = new Email();
}
protected override void OnStart(string[] args)
{
try
{
// Create and start a timer.
m_mainTimer = new System.Timers.Timer();
m_mainTimer.Interval = 5000; // every 5 seconds
m_mainTimer.Elapsed += m_mainTimer_Elapsed;
m_mainTimer.AutoReset = false; // makes it fire only once
m_mainTimer.Start(); // Start
m_timerTaskSuccess = false;
_email.SendEmail("Quay", "(Shopify)Quay Service Started",
"(Shopify)Quay Service Successfuly Started");
EventLog.WriteEntry("(Shopify)Quay Service Started...");
}
catch (Exception ex)
{
// Log/Send Email
_email.SendEmail("Quay", "Error starting (Shopify)Quay Service", ex.Message + " " +
ex.InnerException.Message);
EventLog.WriteEntry("Error starting (Shopify)Quay service and timer..." + ex.Message + " " +
ex.InnerException.Message);
}
}
protected override void OnStop()
{
try
{
// Service stopped. Also stop the timer.
m_mainTimer.Stop();
m_mainTimer.Dispose();
m_mainTimer = null;
_email.SendEmail("Quay", "(Shopify)Quay Service stopped",
"(Shopify)Quay Service Successfuly Stopped");
EventLog.WriteEntry("(Shopify)Quay Service stopped...");
}
catch (Exception ex)
{
_email.SendEmail("Quay", "Error stopping (Shopify)Quay Service", ex.Message + " " +
ex.InnerException.Message);
// Log/Send Email
EventLog.WriteEntry("Error stopping (Shopify)Quay timer and service..." + ex.Message + " " +
ex.InnerException.Message);
}
}
void m_mainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
var orderUoW = new OrderUoW();
orderUoW.Create();
m_timerTaskSuccess = true;
}
catch (Exception ex)
{
//Error with timer elapsed
m_timerTaskSuccess = false;
_email.SendEmail("Quay", "Error creating (Shopify)Quay order(s)", ex.Message + " " +
ex.InnerException.Message);
EventLog.WriteEntry("Error creating (Shopify)Quay order(Time elapsed event)..." + ex.Message
+ " " + ex.InnerException.Message);
}
finally
{
if (m_timerTaskSuccess)
{
m_mainTimer.Start();
}
}
}
}
To get to this point, I "googled" and "SO'ed" to find the best use of timer... I also have a naïve test layer that reproduces what's in the service, I can run through that fine without any exceptions but this one is driving me nuts.
Any help truly appreciated!
//EDIT
A little explanation on:
var orderUoW = new OrderUoW();
orderUoW.Create();
OrderUoW is a class in my service that inherits from BatchOrder which is responsible for many actions including connecting to two databases and polling of the shopify API... OrderUow is purely to decouple from the business layer but giving access to "x" methods.
All works flawlessly for two days but just seems to halt. I'm not hitting request limits within shopify... so at the moment, I'm at a loss.
After many moments of scratching my head and extreme annoyance with the MS Timer Bug.
Not only did it swallow exceptions, the timer did not raise the event! My service was hanging, which was particularly difficult because it also swallowed exceptions.
Now I did go down the route of half implementing with Threading.Timer
Don't use System.Windows.Forms.Timer because it won't work (this only makes sense).
Don't use System.Threading.Timer because it doesn't work, use System.Timers.Timer instead.
Don't use System.Timers.Timer because it doesn't work, use System.Threading.Timer instead.
Related question.
I really could not be bothered with the issues that came with these steps, as my aim was to focus on the business logic. So I made the decision to use Quartz.Net.
It made my life much easier and seems to work perfectly! 45-60 minutes worth of work.
Basic Setup:
1, Nuget > Quartz
2, New Folder(s) > QuartzComponents > Jobs and Schedule
3, Added OrderJob.cs and OrderJobSchedule.cs in respective folders
OrderJob.cs logic:
public sealed class OrderJob : IJob
{
public void Execute(IJobExecutionContext context)
{
var orderUoW = new OrderUoW();
orderUoW.Create();
}
}
Notice that it creates and instance of my UoW?!? logic that it would hit on each pass.
OrderJobSchedule.cs logic:
public sealed class OrderJobSchedule
{
public void Start()
{
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
IJobDetail job = JobBuilder.Create<OrderJob>().Build();
ITrigger trigger = TriggerBuilder.Create()
.WithSimpleSchedule(a => a.WithIntervalInSeconds(15).RepeatForever())
.Build();
scheduler.ScheduleJob(job, trigger);
}
public void Stop()
{
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Shutdown();
}
}
A lot of magic here, but to emphasis on:
JobBuilder.Create<OrderJob>().Build();
a.WithIntervalInSeconds(15).RepeatForever()
Now that's in place we need to add logic to the "guts" of the service:
public partial class QuayService : ServiceBase
{
OrderJobSchedule scheduler;
public QuayService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
scheduler = new OrderJobSchedule();
scheduler.Start();
SendEmail("(Shopify)Quay Service Started",
"(Shopify)Quay Service Successfuly Started");
}
catch (Exception ex)
{
ProcessException(ex, "Error starting (Shopify)Quay Service");
EventLog.WriteEntry("Error starting (Shopify)Quay service and timer..." + ex.Message);
}
}
protected override void OnStop()
{
try
{
if (scheduler != null)
{
scheduler.Stop();
}
SendEmail("(Shopify)Quay Service stopped",
"(Shopify)Quay Service Successfuly Stopped");
}
catch (Exception ex)
{
ProcessException(ex, "Error stopping (Shopify)Quay Service");
EventLog.WriteEntry("Error stopping (Shopify)Quay timer and service..." + ex.Message);
}
}
private void SendEmail(string subject, string body)
{
new Email().SendErrorEmail("Quay", subject, body);
}
private void ProcessException(Exception ex,
string customMessage)
{
var innerException = "";
if (ex.InnerException != null)
innerException = (!string.IsNullOrWhiteSpace(ex.InnerException.Message)) ? ex.InnerException.Message : "";
new Email().SendErrorEmail("Quay", customMessage,
ex.Message + " " + innerException);
}
}
Very easy to set up and solved my horrendous experience with Timers.Timer Whilst I didn't fix the core issue, I came up with a solution and got a bug free working system in place.
Please note to future readers DO NOT USE System.Timers.Timer unless you are prepared to add a "hack'ish" fix.

System.Messaging.MessageQueueException (0x80004005) error while start and stop window services

Actually, I have window service that read MSMQ queuw at an interval. My MSMQ queue is working without an issue but problem is when I stop or start windows service then it's throws an error. The complete error is given below:
**ERROR 65 DAL.MsmqImportListener - A MSMQ error occured
System.Messaging.MessageQueueException (0x80004005)
at System.Messaging.MessageQueue.AsynchronousRequest.End()
at DAL.MsmqImportListener.PeekCompleted(Object sender, PeekCompletedEventArgs e)**
private static void PeekCompleted(object sender, PeekCompletedEventArgs e)
{
var msmq = sender as MessageQueue;
var messageProcessor = e.AsyncResult.AsyncState as MessageProcessorMethod;
try
{
using (var scope = new TransactionScope())
{
msmq.EndPeek(e.AsyncResult);
var message = msmq.ReceiveById(
e.Message.Id,
TimeSpan.FromSeconds(double.Parse(ConfigurationManager.AppSettings["MsmqReceiveTimeout"])),
MessageQueueTransactionType.Automatic);
messageProcessor(message);
scope.Complete();
}
}
catch (MessageQueueException mqe)
{
// Check if timeout...no action if timeout, else log error
if (mqe.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
{
Logger.Error("A MSMQ error occured", mqe);
EmailDispatcher.SendInformationEmail("A MSMQ error occured" + Environment.NewLine + mqe);
}
}
catch (Exception ex)
{
Logger.Error(
string.Format(
CultureInfo.InvariantCulture,
"An unexpected error was encountered, message with id {0} was put in error queue: {1}",
e.Message.Id,
success),
ex);
}
finally
{
msmq.BeginPeek(TimeSpan.FromSeconds(double.Parse(ConfigurationManager.AppSettings["MsmqPeekTimeout"])), messageProcessor);
}
}

Azure Topics worker role stops processing message after 60 seconds

We have a cloud service using a worker role to process messages it receives from a Topic set up on Azure Service Bus.
The message itself seems to arrive intact and is usually received and processed correctly. In some instances however, the message seems to stop processing (Logging abruptly ends and no more references to the message being processed are seen in our WadLogsTable). From my research, this might be happening due to the worker role keeping its connection open and idle for longer than seconds. How would I go about preventing these long-to-process messages from being abandoned?
The code for our worker role is below.
public class WorkerRole : RoleEntryPoint
{
private static StandardKernel _kernel;
private readonly ManualResetEvent _completedEvent = new ManualResetEvent(false);
private BaseRepository<CallData> _callDataRepository;
private BaseRepository<CallLog> _callLogRepository;
private SubscriptionClient _client;
private NamespaceManager _nManager;
private OnMessageOptions _options;
private BaseRepository<Site> _siteRepository;
public override void Run()
{
try
{
List<CallInformation> callInfo;
Trace.WriteLine("Starting processing of messages");
// Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
_client.OnMessage(message =>
{
// Process message from subscription.
Trace.TraceInformation("Call Received. Ready to process message ");
message.RenewLock();
callInfo = message.GetBody<List<CallInformation>>();
writeCallData(callInfo);
Trace.TraceInformation("Call Processed. Clearing from topic.");
}, _options);
}
catch (Exception e)
{
Trace.TraceInformation("Error: " + e.Message + "---" + e.StackTrace);
}
}
private void writeCallData(List<CallInformation> callList)
{
try
{
Trace.TraceInformation("Calls received: " + callList.Count);
foreach (var callInfo in callList)
{
Trace.TraceInformation("Unwrapping call...");
var call = callInfo.CallLog.Unwrap();
Trace.TraceInformation("Begin Processing: Local Call " + call.ID + " with " + callInfo.DataPoints.Length + " datapoints");
Trace.TraceInformation("Inserting Call...");
_callLogRepository.ExecuteSqlCommand(/*SNIP: Insert call*/);
Trace.TraceInformation("Call entry written. Now building datapoint list...");
var datapoints = callInfo.DataPoints.Select(datapoint => datapoint.Unwrap()).ToList();
Trace.TraceInformation("datapoint list constructed. Processing datapoints...");
foreach (var data in datapoints)
{
/*SNIP: Long running code. Insert our datapoints one at a time. Sometimes our messages die in the middle of this foreach. */
}
Trace.TraceInformation("All datapoints written for call with dependable ID " + call.Call_ID);
Trace.TraceInformation("Call Processed successfully.");
}
}
catch (Exception e)
{
Trace.TraceInformation("Call Processing Failed. " + e.Message);
}
}
public override bool OnStart()
{
try
{
var connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
_nManager = NamespaceManager.CreateFromConnectionString(connectionString);
_nManager.Settings.OperationTimeout = new TimeSpan(0,0,10,0);
var topic = new TopicDescription("MyTopic")
{
DuplicateDetectionHistoryTimeWindow = new TimeSpan(0, 0, 10, 0),
DefaultMessageTimeToLive = new TimeSpan(0, 0, 10, 0),
RequiresDuplicateDetection = true,
};
if (!_nManager.TopicExists("MyTopic"))
{
_nManager.CreateTopic(topic);
}
if (!_nManager.SubscriptionExists("MyTopic", "AllMessages"))
{
_nManager.CreateSubscription("MyTopic", "AllMessages");
}
_client = SubscriptionClient.CreateFromConnectionString(connectionString, "MyTopic", "AllMessages",
ReceiveMode.ReceiveAndDelete);
_options = new OnMessageOptions
{
AutoRenewTimeout = TimeSpan.FromMinutes(5),
};
_options.ExceptionReceived += LogErrors;
CreateKernel();
_callLogRepository.ExecuteSqlCommand(/*SNIP: Background processing*/);
}
catch (Exception e)
{
Trace.TraceInformation("Error on roleStart:" + e.Message + "---" + e.StackTrace);
}
return base.OnStart();
}
public override void OnStop()
{
// Close the connection to Service Bus Queue
_client.Close();
_completedEvent.Set();
}
void LogErrors(object sender, ExceptionReceivedEventArgs e)
{
if (e.Exception != null)
{
Trace.TraceInformation("Error: " + e.Exception.Message + "---" + e.Exception.StackTrace);
_client.Close();
}
}
public IKernel CreateKernel()
{
_kernel = new StandardKernel();
/*SNIP: Bind NInjectable repositories */
return _kernel;
}
}
Your Run method does not go on indefinitely. It should look like this:
public override void Run()
{
try
{
Trace.WriteLine("WorkerRole entrypoint called", "Information");
while (true)
{
// Add code here that runs in the role instance
}
}
catch (Exception e)
{
Trace.WriteLine("Exception during Run: " + e.ToString());
// Take other action as needed.
}
}
Taken from the docs:
The Run is considered the Main method for your application. Overriding
the Run method is not required; the default implementation never
returns. If you do override the Run method, your code should block
indefinitely. If the Run method returns, the role is automatically
recycled by raising the Stopping event and calling the OnStop method
so that your shutdown sequences may be executed before the role is
taken offline.
TheDude's response is very close to the correct answer! It turns out he's right that the run method needs to stay alive instead of returning immediately. With Azure Service Bus's message pump mechanism though, you can't place the _client.onMessage(...) inside a while loop, as this results in an error (The message pump has already been initialized).
What actually needs to happen is a a manual reset event needs to be created before the worker role begins executing, and then waited after the message pump code is executed. For documentation on ManualResetEvent, see https://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(v=vs.110).aspx. Additionally, the process is described here: http://www.acousticguitar.pro/questions/607359/using-queueclient-onmessage-in-an-azure-worker-role
My final worker role class looks like this:
public class WorkerRole : RoleEntryPoint
{
private static StandardKernel _kernel;
private readonly ManualResetEvent _completedEvent = new ManualResetEvent(false);
private BaseRepository<CallLog> _callLogRepository;
private SubscriptionClient _client;
private MessagingFactory _mFact;
private NamespaceManager _nManager;
private OnMessageOptions _options;
public override void Run()
{
ManualResetEvent CompletedEvent = new ManualResetEvent(false);
try
{
CallInformation callInfo;
// Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
_client.OnMessage(message =>
{
// Process message from subscription.
Trace.TraceInformation("Call Received. Ready to process message " + message.MessageId);
callInfo = message.GetBody<CallInformation>();
WriteCallData(callInfo);
Trace.TraceInformation("Call Processed. Clearing from topic.");
}, _options);
}
catch (Exception e)
{
Trace.TraceInformation("Error: " + e.Message + "---" + e.StackTrace);
}
CompletedEvent.WaitOne();
}
private void writeCallData(List<CallInformation> callList)
{
try
{
Trace.TraceInformation("Calls received: " + callList.Count);
foreach (var callInfo in callList)
{
Trace.TraceInformation("Unwrapping call...");
var call = callInfo.CallLog.Unwrap();
Trace.TraceInformation("Begin Processing: Local Call " + call.ID + " with " + callInfo.DataPoints.Length + " datapoints");
Trace.TraceInformation("Inserting Call...");
_callLogRepository.ExecuteSqlCommand(/*SNIP: Insert call*/);
Trace.TraceInformation("Call entry written. Now building datapoint list...");
var datapoints = callInfo.DataPoints.Select(datapoint => datapoint.Unwrap()).ToList();
Trace.TraceInformation("datapoint list constructed. Processing datapoints...");
foreach (var data in datapoints)
{
/*SNIP: Long running code. Insert our datapoints one at a time. Sometimes our messages die in the middle of this foreach. */
}
Trace.TraceInformation("All datapoints written for call with dependable ID " + call.Call_ID);
Trace.TraceInformation("Call Processed successfully.");
}
}
catch (Exception e)
{
Trace.TraceInformation("Call Processing Failed. " + e.Message);
}
}
public override bool OnStart()
{
try
{
var connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
_nManager = NamespaceManager.CreateFromConnectionString(connectionString);
_nManager.Settings.OperationTimeout = new TimeSpan(0,0,10,0);
var topic = new TopicDescription("MyTopic")
{
DuplicateDetectionHistoryTimeWindow = new TimeSpan(0, 0, 10, 0),
DefaultMessageTimeToLive = new TimeSpan(0, 0, 10, 0),
RequiresDuplicateDetection = true,
};
if (!_nManager.TopicExists("MyTopic"))
{
_nManager.CreateTopic(topic);
}
if (!_nManager.SubscriptionExists("MyTopic", "AllMessages"))
{
_nManager.CreateSubscription("MyTopic", "AllMessages");
}
_client = SubscriptionClient.CreateFromConnectionString(connectionString, "MyTopic", "AllMessages",
ReceiveMode.ReceiveAndDelete);
_options = new OnMessageOptions
{
AutoRenewTimeout = TimeSpan.FromMinutes(5),
};
_options.ExceptionReceived += LogErrors;
CreateKernel();
_callLogRepository.ExecuteSqlCommand(/*SNIP: Background processing*/);
}
catch (Exception e)
{
Trace.TraceInformation("Error on roleStart:" + e.Message + "---" + e.StackTrace);
}
return base.OnStart();
}
public override void OnStop()
{
// Close the connection to Service Bus Queue
_client.Close();
_completedEvent.Set();
}
void LogErrors(object sender, ExceptionReceivedEventArgs e)
{
if (e.Exception != null)
{
Trace.TraceInformation("Error: " + e.Exception.Message + "---" + e.Exception.StackTrace);
_client.Close();
}
}
public IKernel CreateKernel()
{
_kernel = new StandardKernel();
/*SNIP: Bind NInjectable repositories */
return _kernel;
}
}
You'll notice the presence of the ManualResetEvent and the invocation of WaitOne() at the end of my Run method. I hope someone finds this helpful!

Time out has expired and the operation has not been completed in Service manager

I have a windows service manager, I try to stop the service by the manager. However I got the exception:
Time out has expired and the operation has not been completed
private static void StopService()
{
if (!IsInstalled()) return;
try
{
CFEServiceController c = new CFEServiceController();
c.StopService(ServiceName, 500);
}
catch (Exception ex)
{
Console.WriteLine("Error in Stop service " + ex.Message);
}
}
And:
public void StopService(string serviceName, int timeoutMilliseconds)
{
using (ServiceController service = new ServiceController(serviceName))
{
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
if (service.Status == ServiceControllerStatus.Running)
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
Console.WriteLine("Stop service " + serviceName+" ");
}
}
catch (Exception ex)
{
Console.WriteLine("Error when stop service in code StopService " + ex.Message); // here I got the exception
}
}
}
The problem is because of this:
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
This is happening because your service has not stopped within your timeout. You should either set your timeout higher, or don't set a timeout at all.
You could also try open
"Event Viewer" -> "Windows Logs" -> "Application"
There could be Error Level message that could give you a clue if increasing/unset the number of timeout doesn't help as answered by #gleng.

Windows service starting, but stopping immediately without errors after OnStart()

I've recently converted a TCP-port listening application into a Windows Service, which installs and runs perfectly on my 32bit Vista laptop.
The problem was, after its installation, which works, I attempted to run the service(through Remote Dekstop) on a 64bit Win7 and it neatly handed me an error 1053, basically stating that the service timed out while starting up.
Now I've gotten it to start up without errors, but all it does is exit immediately without any errors or any eventLogging past OnStart.
I've tried replacing my Timer with Threading to see if that might have been the issue with the strange start, but no luck there... Here's the OnStart method of the service and the method that is meant to run continously.
protected override void OnStart(string[] args)
{
myServer.Start();
eventLog1.WriteEntry("Server started.");
mWorker = new Thread(StartUp);
eventLog1.WriteEntry("Starting up CykelScore service.");
mWorker.Start();//Start the service
//timer.Start(); // Start the timer
}
private void StartUp(object arg)
{
while (true)
{
eventLog1.WriteEntry("Running.");
if (mStop.WaitOne(10000)) return;
{
if (Monitor.dataCount > 0)
{
string tmp = "";
eventLog1.WriteEntry("Antal tags: " + Monitor.dataCount.ToString());
lockedUp.WaitOne();
try
{
tmp = Monitor.PopData();
}
catch (Exception ex)
{
eventLog1.WriteEntry("Fejl:" + ex.ToString());
}
eventLog1.WriteEntry("Recieved: " + tmp);
string buffer = tmp;
string antenna = (buffer.Split(',')[0]).Replace(" ", "");
string time = buffer.Split(',')[2];
string RFIDNR = (buffer.Split(',')[1]).Replace(" ", "");
string[] ART = new string[3];
ART[0] = antenna;
ART[1] = RFIDNR;
ART[2] = time;
if (lastreceivedtagID == RFIDNR)
{
eventLog1.WriteEntry("Same tag as last time. No need to check database");
}
else
{
if (!DataHandler.LoggedInCurrentTimespan(ART))
{
try
{
DataHandler.SaveToLocal(ART);
eventLog1.WriteEntry("Data saved to local database");
DataHandler.SendToRemote(tmp, Monitor.server, Monitor.database, Monitor.username, Monitor.password);
eventLog1.WriteEntry("Data sent to remote database");
}
catch (Exception ex)
{
eventLog1.WriteEntry("Fejl" + ex.ToString());
}
}
else
eventLog1.WriteEntry("Discarding data. Already in local database");
}
lastreceivedtagID = RFIDNR;
lockedUp.ReleaseMutex();
}
}
}
}
Does anyone have any idea what might be the issue?

Categories

Resources