I have my Asp.Net WebApi hosted on Godaddy windows shared hosting.
When I access my api from different devices/machines, It takes around 30 sec for first request; after that, it works fine.
What is the issue? Can I make my web api run all the time? If so, how?
I have used Entity framework code first approach . Every time I face this issue when I call this api from my website which is:
Rs Travels - Go to holidays, click on domestic, see the slowness of web api.
Is there any way I can improve the performance of the web api?
If the API is not used often, it will take time on the first request to make things ready, it's the same if you restart IIS generally, things need to warm up.
Internally, we have a custom healthcheck system that calls specific URLs to monitor them, but as a consequence, it also keeps the service alive.
You could also do this fairly simply by creating a windows scheduler task locally, or on any server that simply calls the API periodically. It might be best to implement a specific Monitor method that performs any other keepalives that might be relevant.
Try this as an example Open Website from windows scheduler
It would be kinda difficult to change it since you do not own the web server (and thus its pool). You could try to call the api before you will actually need it (imagine a splash screen). Then it will be ready when you will actually need it. Of course, this will not work if form the initial page you are calling the API...
This worked for me !
https://stackoverflow.com/a/9474978/6426192
static Thread keepAliveThread = new Thread(KeepAlive);
protected void Application_Start()
{
keepAliveThread.Start();
}
protected void Application_End()
{
keepAliveThread.Abort();
}
static void KeepAlive()
{
while (true)
{
WebRequest req = WebRequest.Create("http://www.mywebsite.com/DummyPage.aspx");
req.GetResponse();
try
{
Thread.Sleep(60000);
}
catch (ThreadAbortException)
{
break;
}
}
}
Related
I am trying to find the appropriate way to setup a long running api task using Asp.Net Web API. The tasks I am running could take up to 3 minutes to complete. I have found several links such as QueueBackgroundWorkItem or this post here but am unsure on a few things.
Question:
So I guess I am most confused about the overall structure for this and the appropriate way to even go about it. My task seems to long to use a QueueBackgroundWorkItem but I don't want to implement a fire and forget API call.
What I would like:
I would like to be able to fire a web API task, return a OK response, but continue to poll for the returned data after firing the task. I just have no idea how to even begin implementing a queue system or even how to poll for that data from the Web API.
Other Information:
Using .Net Framework 4.5.2
Front end is asp.net MVC web app
Web API method is called through an AJAX call on my front
Currently send about 30 requests at a time with a long time out. Then as they return I update my UI with returned data from the API.
My current code:
This is what I am doing now which works fine. The only issue is I have to set the timeout to some ridiculous amount on my UI application. Which is why I am trying to find the correct way to implement a long running task/polling/queueing mechanism for long running tasks. Overall just unsure what is out there for solving the problem below.
public NewProjectLogDTO CreateProject(string modelNumber, string orderName = "")
{
try
{
string EplanPort = ConnectToEPLAN();
SetContext(modelNumber, orderName);
AddSchematicToDB(modelNumber, orderName); //accesses DB
ExecuteCreateProjectAction(); //Really long running task about 3 minutes long
DecreasePortCounter(EplanPort);
AddMacrosToDb(modelNumber, orderName); //accesses DB
return GetNewProjectLogFromContext(modelNumber,orderName); //return data from long running task
}
catch (Exception ex)
{
}
}
I'm working on a little project for a basic Youtube remote control, whereby I have a helper app running on my PC, and then can send commands from a website accessed via the web browser on my phone.
Reading through threads on other sites from people trying to do the same thing I've realized it is not a concept that most people would be comfortable with, but I am struggling to think of another way to do it beyond writing a native app for my phone and having it communicate with the helper application internally via WLAN(Would be happy to do this, but don't have the cash to spring for a new mac to develop for my iphone).
If I were to stick with the Website/Winforms model, is there a way to do this in such a way that (most) people would be comfortable running?
The ideas I had so far were:
a) Build a web server into the helper app(Though not sure of the logistics of having it host an ASP.net site)
b) Host the site externally, and have the helper app periodically poll a database/webservice on a server to receive commands (Sketchy and i imagine very resource heavy)
Sorry for the wall of text, I'm capable of running with an idea and building it, I'm just not sure what is possible and considered the 'best' way to do something like this.
Any advice would be appreciated.
Cheers
Edit Thanks, just to be clear, when i say uncomfortable, I mean - Would you be ok with having a website being able to send potentially ANY command to your computer? This seems to be the problem raised in other discussions about this topic. Obviously I'm not trying to do anything malicious, but as I said, it seemed to be a concern.
If this is a controlled environment where you can always open a port on the firewall for incoming communication, you can have the web app make a WCF call back to the Windows Client through the users firewall.
If not (which is what I suspect), you may be better off polling a web service. Just do it every few seconds and whatever you're checking in that web service call (a database?) make sure it's well optimized. Perhaps just have it return some status int/enum or something very light weight to instruct the client on the next call to make (0 = no update, 1 = command1, 2 = command2, etc).
As for how you do the polling, you could do something like:
int seconds = 4;
System.Timers.Timer _clientTimer = new System.Timers.Timer(seconds * 1000);
_clientTimer.AutoReset = false;
_clientTimer.Elapsed += clientTimer_Elapsed;
_clientTimer.Start();
private void clientTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
// Connect to web service, get status, if status != 0 do something...
}
finally
{
_clientTimer.Start();
}
}
NOTE: the auto-reset = false means that each time the Elapsed event fires, the timer is stopped. In the approach I've taken, I let the timer stop so the client can process the web service results and then start the timer once again after it's done. This will help prevent multiple requests from piling up if a connection is real slow.
That's all I can think of :)
I am very new to windows service. I want same functionality in my windows service as it is in my asp.net web application.
It haven't any UI.
I am briefing my web application here so according to that you can guide me how to do it in windows service.
Retrieving very Big image from IMAGE folder which resides in my web application according to certain condition.
Resize those image and store it into database.
Retrive resized images stored in database and store it into server folder called Large and again resize that image in 3 more different size and save into their three respective size folders called List, Mini,*Thumb* on server.
Now i want to build windows service with same functionality and it run on server after every 15 mins.
Hope now i am more clear. please help me in this regards.
my web application code is working fin. but i don't know where to put this code in my windows service as I am very new to windows service.
I tried to put that code onstart and also oncontinue method but that time service not allowed to start. It gives error message this service can not start on your local machine.
OnStart must complete within a 30 (??? iirc) second timeout. I'd suggest spinning off a Thread in OnStart to do the work so that OnStart completes immediately.
protected override void OnStart(string[] args)
{
(new Thread(() => DoLongRunningStartupWork()){IsBackground = true})
.Start();
}
void DoLongRunningStartupWork()
{
//actual startup code
}
You will need to create a method that is called from within the OnStart method. The OnStart method is there purely for configuring the service when it starts up. You'll want something like:
void OnStart()
{
DoSomething();
}
void DoSomething()
{
// Your code here
}
I've seen people use Threads in order to start there Windows Service and get then the Thread does the work that is required.
I'm attempting to recycle an app pool on IIS6 programmatically through a web application. I have searched all over the net and found a bunch of solutions (Most involving impersonation) but none of them seem to work. The most common error I get is E_ACCESSDENIED despite entering a valid username and password. Can anybody point me in the right direction?
The solution I use for this sort of thing (Where you're trying to run a process from ASP.NET that needs administrative privileges) is the following:
Write whatever you need done as a Self hosted WCF service. Preferably an Http REST Service, so it's easy to call (even using just a browser for testing)
Make sure you service is run using an administrator account. You can use the task scheduler to make sure the service is running at all times as well as run using an Administrator account.
Execute methods on the service from your ASP.NET application using a WCF Client
And it works all the time no matter what "process" I'm trying to run from within an ASP.NET application.
Now as far are the details (code) is concerned let me know if you need help. The code below
is the code you'd have in a console application in order to make it a self hosted WCF Service.
In this case it's an Http service listening on port 7654.
static void Main(string[] args)
{
var webServiceHhost = new WebServiceHost(typeof(AppCmdService), new Uri("http://localhost:7654"));
ServiceEndpoint ep = webServiceHhost.AddServiceEndpoint(typeof(AppCmdService), new WebHttpBinding(), "");
var serviceDebugBehavior = webServiceHhost.Description.Behaviors.Find<ServiceDebugBehavior>();
serviceDebugBehavior.HttpHelpPageEnabled = false;
webServiceHhost.Open();
Console.WriteLine("Service is running");
Console.WriteLine("Press enter to quit ");
Console.ReadLine();
webServiceHhost.Close();
}
AppCmdService is a WCF Service class that looks like this (in my case). In your case you probably don't need a response from your service. In my case I'm getting a Json response. The actual implementation of what it is you're trying to do will be different obviously. But I'm assuming you already have that piece worked out. So simply call a method of that class from here.
[ServiceContract]
public class AppCmdService
{
[WebGet(UriTemplate = "/GetCurrentExcutingRequests/?", ResponseFormat= WebMessageFormat.Json)]
[OperationContract]
public IEnumerable<ExecutingRequestJson> GetCurrentExcutingRequests()
{
return CurrentExecutingRequestJsonProvider.GetCurrentExecutingRequests("localhost");
}
}
On your ASP.NET side, you don't really need a WCF client. All you need is a way to make an http call to the service. So you can simply use HttpWebRequest to make the call out to your service, which in turn execute your process.
Hope all of this makes sense?
Maybe this SO question helps you. There are several solutions (also for IIS6):
Restarting (Recycling) an Application Pool
IMHO the best you could do is to decide to go with a concrete approach an then when you run into an exception, to ask a concrete question with the source code of your approach. Otherwise it's just very vage to answer your question.
Can some one give me a best way to implement a daily job with .NET technology.
I have an asp.net application with the sqlserver database hosted in shared hosting, GODaddy in my instance.
My application is used to add / change the data in the database which is performing quite fairly at this time.
I got a new requirement to send some email alerts daily based on some data criteria that were stored in the database.
Initially I thought to write a windows service, but godaddy is not allowing to access the database other than its hosted applications.
Does someone has any idea to send alerts daily at 1:00AM?
Thanks in advance
See Easy Background Tasks in ASP.NET by Jeff Atwood.
Copy/paste from the link:
private static CacheItemRemovedCallback OnCacheRemove = null;
protected void Application_Start(object sender, EventArgs e)
{
AddTask("DoStuff", 60);
}
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 k, object v, CacheItemRemovedReason r)
{
// do stuff here if it matches our taskname, like WebRequest
// re-add our task so it recurs
AddTask(k, Convert.ToInt32(v));
}
I haven't used GoDaddy for anything other than domain registration, so I have no experience with what you can or cannot do on their hosting platform. I also don't know what their support or knowledge base is like, but I'd say your best option is to ask GoDaddy what they recommend. Otherwise, you might keep implementing something that's technically feasible, but is blocked by the hosting company.
If it's not something that's a prime-time application, one quick and dirty thing to do is to have some kind of external bot calling a (secure) web page on the server that fires off the notification process. Not a real solution, but if this site is just a hobby of yours, it could get you by until you find something the host will allow.
Might also be a good time to find a new host, if this one is not meeting your requirements. There are lots of good ASP.NET hosts available these days.
You can use windows scheduler from the web server to schedule a stored procedure call that can send mail based on particular criteria.
osql.exe -S servername -d database -U username -P password -Q "EXEC spAlertOnCriteria"
References:
osql
Task Scheduler
Many hosting providers can request a URL for you every X minutes. I don't know if GoDaddy does, but if so, you could create an ASMX page that kicks off the job, and tell them to execute it automatically.
If they don't, one solution might be to fire off the job in a background thread at every page request. If you do that, make sure you put in code that limits it to running every X minutes or more (perhaps using a static variable or a database table) - read this story
If you can expose a service on the website hosting the application and database -- authenticated service, of course -- then you can hit that service remotely from any box with credentials, pull down the data, and send the mail that way.
This could be an automated process written as a Windows service, an application that is run under the Scheduler, or some button you push at 1:00 AM. Your pick.
Just because the app is the only thing that can access the database doesn't mean you can't expose the data in other ways.
Use either System.Timers, System.Threading to create a instance that is run at a predetermined time. Have that thread execute whatever the task is that you want... Make sure the code is thread safe!