How to schedule a [WebMethod] in Web Services in .net? - c#

I just got to learn a bit about web services in .net (.asmx and all stuff)
For my project i need to schedule a program which cralwels a set of websites and then update the newly available data to the database every 30 minute.
I have created a [WebMethod] for both the crawler code to run and for database updation if available.
But i want that this [WebMethod] get automate and runs for every 30 minutes?

it is not necessary create a WebMethod to do this, you can make in the server side, and for schedule operations, I always use Quartz.net

I may be incorrect but it looks like you want to schedule a background task using asp.net? I haven't used Quartz.Net but I have done this using a simple example provided by Jeff Attwood. The following code is from Global.asax.cs and on application startup schedules a recurring job every 60 minutes:
void Application_Start(object sender, EventArgs e)
{
var refreshMinutes = 60;
AddTask("UpdateInfo",
(int)TimeSpan.FromMinutes(refreshMinutes).TotalSeconds);
}
private void AddTask(string name, int seconds)
{
OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null,
DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable, OnCacheRemove);
}
public void CacheItemRemoved(string key, object v, CacheItemRemovedReason r)
{
if ("UpdateInfo".Equals(key))
{
try
{
new SearchService().UpdateInfo();
}
catch (Exception ex)
{
logger.Error("UpdateInfo threw an exception: {0} {1}", ex.Message, ex.StackTrace);
}
}
AddTask(key, Convert.ToInt32(v));
}
Note Phil Haack has a post on The Dangers of Implementing Recurring Background Tasks In ASP.NET which provides some useful techniques for making the process more robust.

Related

Why does .NetFramework console exe program shut down by itself after 1 day idle?

I have a Console application that is ran on the background. Its a simple server that built using NetMQ library and NLogger that works locally.
I ran the program using taskScheduler with the following command schtasks /create /sc ONSTART /tn "TheServer" /tr "C:\\Temp\TheServer.exe" /ru System
As you can se, now it will start every time the desktop is turned on and it will run as System (It means that we can see TheServer.exe is running as background through Task Manager)
Question:
My timeline was like the follows:
My PC was on on Friday morning (starting of Business day - 09:00 in the morning)
I didn't turn off my PC on Friday before I go back from work
Monday morning, I checked my PC and TheServer is already gone
Does anyone know why it happens and how to prevent it?
FYI, I write my code as follows
Program.cs
class Program
{
[STAThread]
static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
...
static void Main(string[] args)
{
try
{
var inst = Server.GetInstance();
inst.Bind();
inst.Run();
}
catch (Exception e)
{
log.Error(e.Message);
log.Error(e.StackTrace);
throw;
}
}
}
Server.cs
class Server
{
private NetMQ.Sockets.ResponseSocket rSocket = new NetMQ.Sockets.ResponseSocket();
static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
...
public void Bind()
{
try
{
//bind is only for the Responder or The Server
rSocket.Bind("tcp://127.0.0.1:32325");
}
catch (Exception e)
{
log.Error(e.Message);
log.Error(e.StackTrace);
throw;
}
}
public void Run()
{
while (true)
{
var message = server.ReceiveFrameString();
Console.WriteLine("Received {0}", message);
// processing the request
Thread.Sleep(100);
Console.WriteLine("Sending World");
server.SendFrame("World");
}
}
}
I wrap my code at Program.cs with try-catch. But nothing written in the log
Then
I tried to find some information at the Window's Event Viewer. But there are no related information why TheServer.exe stopped
Update:
Looks like I found what #PMF means.
Then one extra question. . .
Is there any way to do that through command prompt?
I tried to read https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks-create Looks like if I didn't set the /du when create the task, it will be forever (?). CMIIW
UPDATE
So yes, we decided to recreate this TheServer.exe as Windows Service. Thanks for your input and opinions.

C# stuck at db call even oracle clear the session automatically after around 30 mins

I am using the C# windows service. I started Timer with 10 seconds.
In every 10 seconds, I called the method, it executes only when thread is null or in suspended state, which start the thread and inside the thread, it calls the oracle db proc.
But when db does not respond after 1 or 2 hr. Oracle clear the session after approx. 30 mins but c# Thread does not receive any communication from oracle and still stuck in oracle db call.
Any help?
private void objTimer_Elapsed(object sender, EventArgs e)
{
if ((_objThread == null) || (_objThread.ThreadState == ThreadState.Suspended))
{
_objThread = new Thread(DBCallMethod);
_objThread.Start();
}
}
private void DBCallMethod()
{
try
{
//DB Called to update the recods.
//stuck here while making db call, even though oracle automatically clear the session after approx 30 mins, cursor still stuck here.
//resolve by restarting the service again.
}
catch (Exception ex)
{
//log the exception using event log
}
finally
{
//log the complete state using event log
if (_objThread.IsAlive)
{
_objThread.Suspend();
}
}
}

Update the interface in the secondary process

I'm using selenium to perform the automation of a web task and I'm generating a simple log ... However, I would like to "unlock" the interface for the log to be inserted in real time and not at the end of the whole process.
Simple log:
void log(string texto)
{
listBox1.Invoke((MethodInvoker)delegate
{
listBox1.Items.Add(string.Format("{0} - {1}", DateTime.Now.ToString(), texto));
});
}
How im using:
//Selenium Code Here (eg.: driver = new ChromeDriver();)
log("ChromeDriver Started!");
But nothing happens, the interface keeps being updated at the end of every process.

ASP.NET App that monitors an external sensor (Multithreading)

I created an MVC 4 App that gets data from some external sensors, and then shows data depending on the values recived. The external sensors expose their values through an http page (e.g. http:///CheckValue). The MVC App must be continiously checking for those values, let´s say every 5 seconds.
The basic Idea is that this process must be done on the background and in a infinite loop, each sensor on a different thread.
The problem is that I don´t know where is the best place to do this, as of now I just create a new Task for each sensor at the Application_Start method on the Global.aspx file.
protected void Application_Start()
{
foreach (var sensor in sensors)
{
Task.Factory.StartNew(() => sensor.readValue(5000));
}
}
This is the code for readValue()
public void readValue(int timespan)
{
try
{
using HttpClient client = new HttpClient())
{
while(true){
try
{
string result = await client.GetStringAsync(url);
//result validation logic
}
catch(Exception)
{
//Exception Handling
}
Thread.Sleep(timespan);
}
}
}catch(Exception e)
{
Debug.Write(e.Message);
}
}
I´m new to ASP.NET so I really don´t know if this should be in the Application_Start method, or if maybe it shouldn´t be on the MVC App at all, and do it on a separate Windows Service (If so how do I send the values back to the MVC App)

Using Web API for a Windows Service to Receive Commands and Perform Tasks via Polling?

I have a project where I need to create a windows service that, when instructed via a command, will perform various tasks. This server would run on multiple servers and would effectively perform the same kind of tasks when requested.
For example, I would like to have a Web API service that listens for requests from the servers.
The service running on the server would send a query to Web API every 25 secs or so and pass to it its SERVERNAME. The Web API logic will then look up the SERVERNAME and look for any status updates for various tasks... I.E., if a status for a DELETE command is a 1, the service would delete the folder containing log files... if a status for a ZIP command is a 1, the service would zip the folder containing log files and FTP them to a centralized location.
This concept seems simple enough, and I think I need a nudge to tell me if this sounds like a good design. I'm thinking of using .NET 4.5 for the Windows Service, so that I can use the HttpClient object and, of course, .NET 4.5 for the Web API/MVC project.
Can someone please get me started on what a basic Web API woudld look like provide status updates to the Windows services that are running and issue commands to them...
I'm thinking of having a simple MVC website that folks will have a list of servers (maybe based on a simple XML file or something) that they can click various radio buttons to turn on "DELETE", "ZIP" or whatever, to trigger the task on the service.
I do something similar. I have a main Web API (a Windows Service) that drives my application and has a resource called /Heartbeat.
I also have a second Windows Service that has a timer fire every 30 seconds. Each time the timer fires it calls POST /heartbeat. When the heartbeat request is handled, it goes looking for tasks that have been scheduled.
The advantage of this approach is that the service makes the hearbeat request is extremely simple and never has to be updated. All the logic relating to what happens on a heartbeat is in the main service.
The guts of the service are this. It's old code so it is still using HttpWebRequest instead of HttpClient, but that's trivial to change.
public partial class HeartbeatService : ServiceBase {
readonly Timer _Timer = new System.Timers.Timer();
private string _heartbeatTarget;
public HeartbeatService() {
Trace.TraceInformation("Initializing Heartbeat Service");
InitializeComponent();
this.ServiceName = "TavisHeartbeat";
}
protected override void OnStart(string[] args) {
Trace.TraceInformation("Starting...");
_Timer.Enabled = true;
_Timer.Interval = Properties.Settings.Default.IntervalMinutes * 1000 * 60;
_Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
_heartbeatTarget = Properties.Settings.Default.TargetUrl;
}
protected override void OnStop() {
_Timer.Enabled = false;
}
private void _Timer_Elapsed(object sender, ElapsedEventArgs e) {
Trace.TraceInformation("Heartbeat event triggered");
try {
var httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(_heartbeatTarget);
httpWebRequest.ContentLength = 0;
httpWebRequest.Method = "POST";
var response = (HttpWebResponse)httpWebRequest.GetResponse();
Trace.TraceInformation("Http Response : " + response.StatusCode + " " + response.StatusDescription);
} catch (Exception ex) {
string errorMessage = ex.Message;
while (ex.InnerException != null) {
errorMessage = errorMessage + Environment.NewLine + ex.InnerException.Message;
ex = ex.InnerException;
}
Trace.TraceError(errorMessage);
}
}
}
You can do it with ServiceController.ExecuteCommand() method from .NET.
With the method you can sand custom command to windows' service.
Then in your service you need to implement ServiceBase.OnCustomCommand() to serve incomming custom command event in service.
const int SmartRestart = 8;
...
//APPLICATION TO SEND COMMAND
service.ExecuteCommand(SmartRestart);
...
//SERVICE
protected override void OnCustomCommand(int command)
{
if (command == SmartRestart)
{
// ...
}
}

Categories