Sithira Pathmila
Sithira Pathmila

Reputation: 145

Error in C# threading application

I have created 4 projects to online examination time monitoring

  1. ASP.NET application to examination
  2. Class Library for Business Process and Data Access
  3. Class Library to database execution
  4. Windows form application to monitor examination time

in Windows form application I use threads for monitor when new exam start and I want to indicate notification before 5 munites to end the examination.

when using visual studio for debug the app its not getting any error. but manually click the .exe file and run the application it getting an error "application stopped working"

This is my code for windows form application

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Thread t;
    Thread t1;

    private void Form1_Load(object sender, EventArgs e)
    {

        fillList();           
        CheckForIllegalCrossThreadCalls = false;
        t= new Thread(()=>getTrigger());
        t1 = new Thread(() => TimeOption());
        t.Start();
        t1.Start();
       // getTrigger();
    }


    private  void getTrigger()
    {

        int temp = StudentExamDB.getPendingCount();

        while (true)
        {
            if (temp != StudentExamDB.getPendingCount())
            {
                fillList();
                temp = StudentExamDB.getPendingCount();

            }
        }

    }
    List<string> added = new List<string>();
    private void TimeOption()
    {
        while(true)
        {
            DataTable dt = StudentExamDB.getFinishingList();
            foreach (DataRow dr in dt.Rows)
            {
                try
                {
                    for (int i = 0; i < dataGridView1.Rows.Count; i++)
                    {

                        if (dataGridView1.Rows[i].Cells["enrollmentid"].Value.ToString() == dr["enrollmentid"].ToString())
                        {
                            if (added.Contains(dr["enrollmentid"].ToString()))
                            {
                            }
                            else
                            {
                                notifyIcon1.BalloonTipTitle = "Ending Some Examinations";
                                notifyIcon1.BalloonTipText = "click here to show more details about examination time";
                                notifyIcon1.ShowBalloonTip(5000);

                                added.Add(dr["enrollmentid"].ToString());



                            }
                            dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Tomato;
                            dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.White;



                        }
                    }
                }
                catch
                {
                }
            }
        }            
    }

    private void fillList()
    {
        try
        {
            dataGridView1.DataSource = StudentExamDB.getPendingList();
        }
        catch
        {
        }            
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        t.Abort();
        t1.Abort();
    }

    private void setToFinishedToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            StudentExamDB.updateStatus(int.Parse(dataGridView1.CurrentRow.Cells["enrollmentid"].Value.ToString()));
            fillList();

        }
        catch
        {
        }
    }       
}

Upvotes: 1

Views: 121

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499740

Are you aware of what this does?

CheckForIllegalCrossThreadCalls = false;

You're explicitly turning off checks for what you're doing wrong. That suggests that you know you shouldn't be modifying the UI on a non-UI thread, but you're doing it anyway. If you didn't have that line of code, you certainly would get exceptions when running in Visual Studio.

That's at least one of the problems. Your TimeOption method is running on a non-UI thread, but it's modifying the UI. Just don't do that. There are various other options, including BackgroundWorker and Control.Invoke/BeginInvoke.

Then...

  • You've got tight loops in both TimeOption and getTrigger. Basically you're going to be pounding the database hard, forever. That's a really bad idea. You should at least have a delay between iterations
  • You've got empty catch blocks all over the place: catch {}. That's basically claiming that whatever goes wrong, you're fine - you can just keep going and ignore it, without even logging what's happened. Don't do that.
  • You're using Thread.Abort to kill your threads. Don't do that. In this case it would be pretty simple to use a volatile bool field indicating when you want to finish, and check it on each iteration of the loop.

I suspect the problems are due to your inappropriate access to the UI from a different thread - but I can't say for sure. Fix all of the above and you'll have a much better codebase to then diagnose any problems which still remain.

Upvotes: 4

Related Questions