I have a SharePoint 2010 webpart that is timing out after 5 minutes when on the QA servers. The QA environment is 1 web server, 2 app servers, and a SQL server. I've tried EVERYTHING to fix this. Changed the IIS timeouts, worker failures, disabled ping checks and nothing works. It's the simplest code in the world!!
Could someone please try this on one of your environments? Preferably one with multiple servers making up the farm. This code works perfectly on our dev servers which is just one box. All I am doing is calling the SPLongOperation, sleeping for 6 minutes, and ending the long operation.
Anyone have a clue what I'm missing?
Code:
protected void btnTest_Click(object sender, EventArgs e)
{
string currentUrl = SPContext.Current.Web.Url;
using (SPLongOperation operation = new SPLongOperation(this.Page))
{
operation.LeadingHTML = "Updating Reports on Selected Project Sites";
operation.TrailingHTML = "Gathering the worker threads, this could take a second. Please stand by...";
operation.Begin();
Thread.Sleep(360000);
operation.End(currentUrl, SPRedirectFlags.Default, this.Context, "");
}
SetStatus("Slept for a long time!", false);
}
Interestingly, if I run the below operation where I don't navigate to the long operation page, it makes me re-authenticate but then redirects me to the "Internet Explorer cannot display the webpage" screen. Very odd.
protected void btnTest2_Click(object sender, EventArgs e)
{
SetStatus("Before Sleep", false);
Thread.Sleep(360000);
SetStatus("Sleep Successful!", false);
}
Related
Can anyone explain the following behaviour of an ASP.net webform on IIS. When I have a page and start it 4 times, the pages are served synchroniously. In other words if this page takes about 10 seconds to build, I see the first page appear at around 10sec, 2nd at 20sec, 3rd at 30sec, 4th at 40sec. When asking the threadnumber I usually see 2 threadnumbers, which makes me think IIS/ASP.net is only having two threads in IIS per application pool?
Small example:
protected void Page_Load(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(10000);
this.Label1.Text = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
}
When I look for suggestions on the internet I find that I should program asynchroniously and for example use await Task.Delay to not block the thread, but I still have the same result when I use this Page_Load:
protected async void Page_Load(object sender, EventArgs e)
{
await System.Threading.Tasks.Task.Delay(10000);
this.Label1.Text = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
}
Can anyone explain me this behaviour? First of all if there are two threads I would expect two pages being served at 10sec and the 3rd and 4th at 20sec. But even when I run the code with async it doesn't really make much/any difference. How can I circumvent this blocking of threads with an easy solution?
Best regards,
Rémy Samulski
EDIT: I was calling the website from the same browser and the same URL. This caused the issue. Thx to Richard for helping me figuring out my mistake.
Given the code:
protected void Application_Start(object sender, EventArgs e)
{
var testTimer = new Timer(
LogTimer,
null,
new TimeSpan(0, 0, 0, 0),
new TimeSpan(0, 0, 0, 1)
);
}
public static void LogTimer(object sender)
{
"Hello".Log();
}
At seemingly random occasions the timer stops firing, and wont start again unless I restart the website.
It doesn't throw any exceptions, but looking in the Windows error log there are some entries:
The Open Procedure for service "Lsa" in DLL "C:\Windows\System32\Secur32.dll" failed. Performance data for this service will not be available. The first four bytes (DWORD) of the Data section contains the error code.
Unable to open the Server service performance object. The first four bytes (DWORD) of the Data section contains the status code.
The site is active (the start mode of the app pool is AlwaysRunning.
I understand that using timers in this way is not a recommended approach for critical things for exactly this reason, but I am failing to come up with an explanation as to why it's silently and apparently randomly just giving up.
From your code, I expect the garbage collector to collect your timer since there is no handle for that. have you tried something like
static Timer testTimer ;
protected void Application_Start(object sender, EventArgs e)
{
testTimer = new Timer(...);
}
ASP.NET isn't suited to running timers due to the way AppDomains get unloaded, the threading model and many other factors.
I suggest you read this blog post from Scott Hanselman that discusses various ways to successfully run timer-based code in ASP.NET web applications.
How do I count the number of visitors for website in asp.net c#?
I am using the code below:
In global.asax page:
<%# Application Language="C#" %>
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
Application["NoOfVisitors"] = 0;
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
In .aspx page:
<asp:Label runat="server" ID="lbluser" />
In .aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
lbluser.Text = Application["NoOfVisitors"].ToString();
}
The application counter is resetting to 0 every one hour ...
Where have I erred in counting the number of users?
Application State is volatile. Check the this MSDN articule:
When using application state, you must be aware of the following
important considerations:
...
Volatility Because application state is stored in server memory, it
is lost whenever the application is stopped or restarted. For example,
if the Web.config file is changed, the application is restarted and
all application state is lost unless application state values have
been written to a non-volatile storage medium such as a database.
So you should not use that for saving this kind of data that you want to persist over time. Because applications pools get reseted from time to time. And I suspect you don't want to reset your visitor count when that happens.
You'll need some kind of data store which can persist your data when you application is not running.
Here are some choices:
File (XML, JSON, plain text, etc.): sample xml code for visitors counter
Database (SQL Server, SQLite, etc.): sample database code for hit counter
In global.asax file under this method
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
then in your page load please add
lblCount.Text = Application["NoOfVisitors"].ToString();
then you can get the number of visitors on your site .
If your application is hosted in IIS and has an application pool, you can check the Application Pool Recycling Settings. Depending on your version, the default is 1740 or 29 hours. Maybe the pool for your application is configured to 60 or around that value? The next setting to check is the Idle Time Out. I believe its default value is 20 on a new server. You can set this to 0. I recommend you read about these settings prior to changing them.
The only possible reason reason could be that, have you hosted your application on a third party server? if yes, it could be that the provider might be killing your application. i have numerous cases where these providers kill your application depending on their memory management schemes.
Simple store the visitor count after changing its value to database and on application start load this value from database that's all you have to do.
You should save count for visits on fly on an xml file under root directory. Check following blog for complete steps :How to count number of visitors in asp.net website
If you want to manage visitor on code level you need to start visitor counter under Application_Start method in application configuration file after need to increase the counter on every session. For more details follow the link given below.
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
http://www.freshcodehub.com/Article/49/show-number-of-visitors-in-aspnet-application
Application Pool Restart periodically default settings is 60 minutes.
when app pool restart the count restart as well.
I'm trying to create a task scheduler that runs twice a day. I've implemented a task scheduler using CacheItemRemovedCallaback, as suggested in this post and this blog. I have the a feature that enables the admin to modified the scheduled times, and saves them on Application variables:
protected void UpdateSchedule(object sender, EventArgs e)
{
Button button = sender as Button;
if (button.ID == "scheduleButton1")
{
Application.Lock();
Application["buildSchedule1"] = GetScheduleTime1;
Application.UnLock();
}
else if (button.ID == "scheduleButton2")
{
Application.Lock();
Application["buildSchedule2"] = GetScheduleTime2;
Application.UnLock();
}
HttpRuntime.Cache.Remove(Global.DummyCachekey); //remove current scheduled task and set new time
}
And on Global.aspx I have:
protected void Application_Start(object sender, EventArgs e)
{
Application.Lock();
Application["buildSchedule1"] = new TimeSpan(10,00, 0); //default time
Application["buildSchedule2"] = new TimeSpan(16,00, 0); //default time
Application.UnLock();
SheduleTask();
};
The problem is that for some reason (probably due to app pool recycling) the schedule times get reset, and even some times the task won't start at the default times.
I found solutions that mention Windows services or Windows task scheduler, but that doesn't work for me since I need to be able to let the admin configure the times through the web application. (I search for this, but couldn't find anything).
I found solutions that mention Windows services or Windows task scheduler
That's what you should be using. A web application doesn't "always run." It responds to requests, that's all. Unless something is actively making a request to the website, it's not doing anything.
but that doesn't work for me since I need to be able to let the admin configure the times through the web application
Sure it does. More than one application can share a single database. In this case you'd have two applications:
A Web Application where users can login and maintain the data related to the scheduled tasks.
A Windows Service (or scheduled Console Application) which runs in the background on the server and executes the configured tasks which it reads from the database.
Using hacks like Windows Scheduled Tasks and Control Panel abilities are not nice solutions. They sucks most of the time, they are a headache.
You can use ATrigger scheduling service. A .Net library is also available to create scheduled tasks without overhead.
//Tags: Tags are required to identify tasks.
//read more at: http://atrigger.com/docs/wiki/9/rest-api-v10-parameter-tag_
Dictionary<string, string> tags = new Dictionary<string, string>();
tags.Add("type", "test");
//Create
ATrigger.Client.doCreate(TimeQuantity.Hour(), "12", "http://www.example.com/myTask?something", tags);
Disclaimer: I was among the ATrigger team. It's a freeware and I have not any commercial purpose.
I'm using WebKitDotNet to simulate and automate a web browser. This is really nifty and works in most respects. However, when I try to implement this code, WebKit doesn't trigger a download:
WebKitBrowser _b = null;
private void button1_Click(object sender, EventArgs e)
{
_b = new WebKitBrowser();
_b.DownloadBegin += new FileDownloadBeginEventHandler(b_DownloadBegin);
_b.Error += new WebKitBrowserErrorEventHandler(_b_Error);
_b.AllowDownloads = true;
_b.Navigate("http://sourceforge.net/projects/webkitdotnet/files/WebKit%20.NET%200.x/0.5/WebKit.NET-0.5-bin-cairo.zip/download");
}
void _b_Error(object sender, WebKitBrowserErrorEventArgs e)
{
MessageBox.Show("error!");
}
void b_DownloadBegin(object sender, FileDownloadBeginEventArgs e)
{
MessageBox.Show("hi");
}
Neither the "Error" nor the "DownloadBegin" events fire. I would expect at least one of them to do so - is there a setting that I'm missing?
EDIT: I know this is an old question, but here's the update. When I wrote this question, I was trying to automate a process that required a human being - once per day - to log onto a website, provide credentials, and click a download link. We were hoping to be able to do this programmatically to relieve the monotony for the poor person tasked with doing this job.
Unfortunately, WebKitDotNet did not succeed in this task. Although, in a webkit based browser, you can click on the link and trigger a download, in the embedded WebKitDotNet clicking on the link did nothing. My guess is that something within WebKitDotNet lost the event. If anyone wants to test this, you can use the Sourceforge download link to test.
One of the guys on my team did eventually solve this problem by using an Internet Explorer automation tool called "IMacros". We selected this product because 1) We could guarantee that IE was installed on every computer that would run the program, and 2) IMacros could correctly receive the event from the website and trigger the file download.
On the Issue tracker there is a post date from March 24, 2011 in which is stated that download does not work yet:
https://github.com/webkitdotnet/webkitdotnet/issues/7
Since there are few issues in the tracker, it would have probably been marked as resolved if the feature was added meantime.