2

I am running an ASP 4.5 application. One one of the pages the user must answer several questions and the push the button to finish the test. My application uses a text file to analyze the users answers. If the user does everything quickly the application works fine, but when it takes longer then 20 min for him to finish the test I get an exception

Cannot read from a closed TextReader

I do not understand what's wrong, because I open StreamReader only when the button is pressed. This is a part of my code:

 protected void Page_Load(object sender, EventArgs e)
 {
    if (!IsPostBack)
    {
        GlobalVariables.surname = Request.QueryString["surname"];
        GlobalVariables.name = Request.QueryString["name"];
        GlobalVariables.gender = Request.QueryString["gender"];
        GlobalVariables.age = int.Parse(Request.QueryString["age"]);
    } 
    Label1.Width = 700;
    Button1.Click += new EventHandler(this.Button1_Click);
 }

 void Button1_Click(Object sender, EventArgs e)
 {
    var f0= new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read);
    StreamReader sr = new StreamReader(f0); 
    //..... 
    sr.Close();
    sr.Dispose();
  }

Could somebody help me please?

user2080209
  • 749
  • 3
  • 8
  • 25
  • 1
    Please show the *full* exception stack trace - and put more effort into formatting the code in your question; it's all over the place at the moment. – Jon Skeet Mar 11 '15 at 13:35
  • 1
    If the page is not a post back, you would want to set up the page as it should be viewed the first time. I would also suggest moving the button click even within the `if(!Page.IsPostBack)` as well as anything that needs to be setup before a post-back. Move your Stream reader to the else... like so `if(!Page.IsPostBack) else { stream reader stuff }` and remove the button click even in general since the button causes postback. – Andrew Grinder Mar 11 '15 at 13:53
  • @AndrewGrinder thank you for your advice, I'll try it and see in half an hour if it works – user2080209 Mar 11 '15 at 14:02
  • Does 1 "mis" = 1 minute? – Ross Brasseaux Mar 11 '15 at 14:32
  • @Lopsided yes, sorry – user2080209 Mar 11 '15 at 14:34

3 Answers3

2

when it takes longer then 20 mis for him to finish the test I get an exception

That sounds a lot like their session expired. To fix this, I recommend adding some javascript to establish a heartbeat to the web server. The heartbeat will keep the session alive; it doesn't need to do anything other than simply make a request every minute or so, so the server knows you're still there.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Could you please give an example of such a heartbeat? I'm a bigenner in javascript. I thoght about session too and tried to add sessionState timeout="300" to web.config, but it didn't work – user2080209 Mar 11 '15 at 15:06
  • That has to be the session. Make sure you are setting it correctly, that it isn't being set somewhere else, etc. – Steve Mar 11 '15 at 15:14
  • This is the part of my web.config: – user2080209 Mar 11 '15 at 15:21
  • I do not see a mistake in it – user2080209 Mar 11 '15 at 15:22
  • @user2080209 Start managing it. Separate reading the text file from processing it as in my answer. Put in some error handling so you can better isolate the error. Test for session variables. – paparazzo Mar 11 '15 at 15:33
1

In addition to the answer from Joel I would recommend to separate processing the file from reading the file.

List<string> lines = new List<string>();
using (var f0 = new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read))
{
    string line;
    using (StreamReader reader = new StreamReader(f0))
    {
        while ((line = reader.ReadLine()) != null)
        {    
            lines.add(line);
        }
    }
}

// it would need to be a very big text file to be a memory issue
// do your processing here
paparazzo
  • 44,497
  • 23
  • 105
  • 176
-1

f the page is not a post back, you would want to set up the page as it should be viewed the first time. I would also suggest moving the button click even within the if(!Page.IsPostBack) as well as anything that needs to be setup before a post-back. Move your Stream reader to the else... like so if(!Page.IsPostBack) else { stream reader stuff } and remove the button click even in general since the button causes postback.

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        GlobalVariables.surname = Request.QueryString["surname"];
        GlobalVariables.name = Request.QueryString["name"];
        GlobalVariables.gender = Request.QueryString["gender"];
        GlobalVariables.age = int.Parse(Request.QueryString["age"]);
        Label1.Width = 700;
    }
    else
    {
        DoPostBackStuff();
    }
}

private void DoPostBackStuff()
{
    var f0= new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read);
    StreamReader sr = new StreamReader(f0); 
    //..... 
    sr.Close();
    sr.Dispose();
}
Andrew Grinder
  • 585
  • 5
  • 21