Windows Develop Bookmark and Share   
 index > Windows Forms General > Multi-threading in graphical WF application.
 

Multi-threading in graphical WF application.

I made 2 objects (panels), so one ine while(true) cycle is going on the Form. The other is controlled by keyboard. All events are in their own threads.
But When i press the key, panel on1 stops until panel 2 make it's motion to the end.
How to make them parallel?
RobinMW  Tuesday, July 14, 2009 5:08 PM
use a background worker
Kenneth
Kenneth Haugland  Tuesday, July 14, 2009 8:08 PM
Thanks. I'll read it. Not sure if it'll help.

Not sure, huh. Try running the MVC sample. It is what is known an an Aggregate Pattern. A pattern of design patterns.

1. Note the fact that any change in the Model are automatically updating the Views. Hands-free. The event registration process takes care of all of it. The Model simply reports that changes were made. The Model implements the Observer Pattern.

2. Note the fact that the Form/View does not need to show everyfacet, or variable,in the Model. There is nothing wrong with a Form/View that displayed only a portion of the Model.

3. Note that the Form/View classes do not contain any reference whatsoever to the Model. The View class is not coupled to the Model. This allows you to write any type of View class that you wish and it will work just fine. The View implements the Command Pattern.

4. Note how there is only one instance of the Controller, and that any and all user actions are reported to the Controller instance. Multiple controllers could be used to service various parts of the Model. A Master Controller could even supervise a group of these sub-controllers. The Controller implements the Mediator Pattern.

5. Note that a Controller does not have to restrict itself to just a single Model. You could add a Data Access Layer between the Controller and the Model, which implemented the Bridge and/or Adaptor Pattern.

Just some food for thought.

Rudedog =8^D
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 1:42 PM

Your snippet may be incomplete or otherwise damaged. It has a couple of issues that cause it not to compile.

1. The button1_KeyDown() method contains a stray character. Did you have a copy/paste error?

2. The button1_Click() method contains the following line ...

oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));

...which will not compile because of a delegate signature mismatch.

So, I deleted the stray character in #1 and made the following change for #2.


void RectMove()
{
this.RectMove(new object(), new DoWorkEventArgs(new object()));
}

private void button1_Click(object sender, EventArgs e)
{
Delegate1 = new MyDelegate1(PanelTopInc);
Delegate2 = new MyDelegate1(PanelLeftInc);
//
//oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));
ThreadStart threadStarter = new ThreadStart(RectMove);
oThread = new Thread(threadStarter);
//
oThread.Priority = System.Threading.ThreadPriority.Highest;
oThread.Start();

}

I also added a couple of panels and a button.


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 4:04 PM
use a background worker
Kenneth
Kenneth Haugland  Tuesday, July 14, 2009 8:08 PM
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/a9759c21-3af4-4ecd-b7ad-66c8b390fa68/

Take a look at that thread a the many links within it by myself and others.
Post back with any questions.

If it takes you a week to get back, I understand.
It took me month to wrap my head around that stuff.
Integrating MVC and a BGW, backgroundworker, is not too overcompicated. Itis just simplynot easy to do.

Hope this helps.

Rudedog =8^D
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Tuesday, July 14, 2009 8:29 PM
Kenneth, it didn't help.
RobinMW  Tuesday, July 14, 2009 8:32 PM
Thanks. I'll read it. Not sure if it'll help.
RobinMW  Tuesday, July 14, 2009 8:33 PM
Also, it's said about BGW:

"You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events. "
RobinMW  Wednesday, July 15, 2009 1:31 PM
Thanks. I'll read it. Not sure if it'll help.

Not sure, huh. Try running the MVC sample. It is what is known an an Aggregate Pattern. A pattern of design patterns.

1. Note the fact that any change in the Model are automatically updating the Views. Hands-free. The event registration process takes care of all of it. The Model simply reports that changes were made. The Model implements the Observer Pattern.

2. Note the fact that the Form/View does not need to show everyfacet, or variable,in the Model. There is nothing wrong with a Form/View that displayed only a portion of the Model.

3. Note that the Form/View classes do not contain any reference whatsoever to the Model. The View class is not coupled to the Model. This allows you to write any type of View class that you wish and it will work just fine. The View implements the Command Pattern.

4. Note how there is only one instance of the Controller, and that any and all user actions are reported to the Controller instance. Multiple controllers could be used to service various parts of the Model. A Master Controller could even supervise a group of these sub-controllers. The Controller implements the Mediator Pattern.

5. Note that a Controller does not have to restrict itself to just a single Model. You could add a Data Access Layer between the Controller and the Model, which implemented the Bridge and/or Adaptor Pattern.

Just some food for thought.

Rudedog =8^D
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 1:42 PM
Thanks for answer. I'm not quite understand yet about MVC model. Doesn't WF have it's own mvc for UI at least?
Could you give a pair of articles about that all (MVC, WF model etc.) please?
RobinMW  Wednesday, July 15, 2009 1:46 PM

Generally, articles relating to WF, Windows Forms, are pretty rare.
Most any article that youturn up with a Google search pertains to ASP.NET and web applications in general.
No Forms applications. That was my motivation for making that sample for that thread, and other previous threads.
That sample sort of evolved into what is posted at the most recent link that I gave you.

MVC has been around for quite a while, and improvements have been made in newer patterns inspired by MVC. If you do nota basic familiarity with some ofthe Original 23 Gof Design Patterns, then you might have a more difficult time understanding a mixture of them.


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 1:54 PM
Thanks. i'll try to go through that to understand how to solve my problem and your MVC WF sample. By the way, it's diveded to several parts? Or is there 1 complete cs file?
RobinMW  Wednesday, July 15, 2009 2:09 PM
Thanks. i'll try to go through that to understand how to solve my problem and your MVC WF sample. By the way, it's diveded to several parts? Or is there 1 complete cs file?

It is divided into several parts, as it should be. Every class should have its' own file, particularly when those files are to be used with any of the Wizards and Designers that are part of the Visual Studio IDE.Most of the IDE'stools tend to assume there is only one class per file.

For example, the Form Designer will only recognize the first class in a file. It will tend to ignore the rest of the file. Never put multiple forms or controls inside of one file. Rather, provide each with its' own separate file.

Besides, separate files really make the organization and editing much easier within the tabbed Coded Editing Window.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 2:15 PM
All right. And could you give an article about threads - Main thread and others. I'm not quite understand why don't my code work (with threads).
RobinMW  Wednesday, July 15, 2009 2:28 PM
Postsome code the demonstrates your problemso that someone can take a look.
Creating a separate test/demo might be best.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 3:20 PM
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ApplicationGraphics
{
    public partial class Form1 : Form
    {
        Form1 MainForm;
        public Form1()
        {
            InitializeComponent();
            MainForm = this; 
        }

        int deltax = 2;
        int deltay = 2;
        public delegate void MyDelegate1();
        System.Threading.Thread oThread;

        MyDelegate1 Delegate1;
        MyDelegate1 Delegate2;

        void PanelTopInc()
        {
            panel1.Top += deltay;
        }

        void PanelLeftInc()
        {
            panel1.Left += deltax;
        }

        void RectMove()
        {
            
            
            //for (int i = 0; i < 1000; i++)
            while(true)
            {
                panel1.Invoke(Delegate1);// Top += deltay; 
                panel1.Invoke(Delegate2);// Left += deltax;
                if ((panel1.Top + panel1.Height + 30) >= MainForm.Height) deltay = -deltay;
                if ((panel1.Left + panel1.Width + 5) >= MainForm.Width) deltax = -deltax;
                if ((panel1.Top) <= 0) deltay = -deltay;
                if ((panel1.Left) <= 0) deltax = -deltax;

                System.Threading.Thread.Sleep(10);
            }
        }
       
        private void button1_Click(object sender, EventArgs e)
        {
            Delegate1 = new MyDelegate1(PanelTopInc);
            Delegate2 = new MyDelegate1(PanelLeftInc);
            
            oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));
            oThread.Priority = System.Threading.ThreadPriority.Highest;
            oThread.Start();

        }

        void Panel2TopInc()
        {
            for (int i = 0; i < 20; i++) { panel2.Top -= 2; System.Threading.Thread.Sleep(20); }
        }

        void Panel2TopDec()
        {
            for (int i = 0; i < 20; i++) { panel2.Top += 2; System.Threading.Thread.Sleep(20); }
        }
                
        void Panel2Top1()
        {
            MyDelegate1 MyDelegate = new MyDelegate1(Panel2TopInc);
            panel2.Invoke(MyDelegate);
        }

        void Panel2Top2()
        {
            MyDelegate1 MyDelegate = new MyDelegate1(Panel2TopDec);
            panel2.Invoke(MyDelegate);
        }


        
        private void button1_KeyDown(object sender, KeyEventArgs e)
        {
            System.Threading.Thread oThread1 = new System.Threading.Thread(new System.Threading.ThreadStart(Panel2Top1));
            System.Threading.Thread oThread2 = new System.Threading.Thread(new System.Threading.ThreadStart(Panel2Top2));

            if (e.KeyData == Keys.A) oThread1.Start();
            if (e.KeyData == Keys.Z) oThread2.Start();
        }


    }
}


Well, it's simple. It makes 3 threads (1 - while(true), 2,3 - For controllling - A and Z keys). Well it has 3 separate threads. All are not main and have a time to sleep.
  • Edited byRobinMW Wednesday, July 15, 2009 4:09 PM
  • Edited byRobinMW Wednesday, July 22, 2009 1:00 PM
  • Edited byRobinMW Wednesday, July 22, 2009 1:00 PM
  •  
RobinMW  Wednesday, July 15, 2009 3:44 PM

Your snippet may be incomplete or otherwise damaged. It has a couple of issues that cause it not to compile.

1. The button1_KeyDown() method contains a stray character. Did you have a copy/paste error?

2. The button1_Click() method contains the following line ...

oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));

...which will not compile because of a delegate signature mismatch.

So, I deleted the stray character in #1 and made the following change for #2.


void RectMove()
{
this.RectMove(new object(), new DoWorkEventArgs(new object()));
}

private void button1_Click(object sender, EventArgs e)
{
Delegate1 = new MyDelegate1(PanelTopInc);
Delegate2 = new MyDelegate1(PanelLeftInc);
//
//oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));
ThreadStart threadStarter = new ThreadStart(RectMove);
oThread = new Thread(threadStarter);
//
oThread.Priority = System.Threading.ThreadPriority.Highest;
oThread.Start();

}

I also added a couple of panels and a button.


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 4:04 PM

...almost forgot. The while loop is an infinite loop.

void RectMove(object sender, DoWorkEventArgs e)
{


//for (int i = 0; i < 1000; i++)
while(true)
{
panel1.Invoke(Delegate1);// Top += deltay;
panel1.Invoke(Delegate2);// Left += deltax;
if ((panel1.Top + panel1.Height + 30) >= MainForm.Height) deltay = -deltay;
if ((panel1.Left + panel1.Width + 5) >= MainForm.Width) deltax = -deltax;
if ((panel1.Top) <= 0) deltay = -deltay;
if ((panel1.Left) <= 0) deltax = -deltax;

System.Threading.Thread.Sleep(10);
}
}


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 4:05 PM
Sorry, i corrected it. The 1 - it's my mistake, 2 - it's because of my experiments with BGW. You right, it should be read so.
I know about while(true) - i would make it stop a bit sooner. But it doesn't work now.
RobinMW  Wednesday, July 15, 2009 4:10 PM
I am having trouble deciding how to setup my 2 panels and a button.

What should the code do? I do not see a BackgroundWorker object, just Thread objects.
The BGW is far easier to use, and it's a good way to understand how threads work.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 15, 2009 4:21 PM
Just drop the button1 anywhere on form, panel1 and panel2 too, just anywhere, but set the backcolor to black or some to see them.
No, I've tried the same but instead of thread made a BGW, it didn't help, so I turned it back to thread now.
RobinMW  Wednesday, July 15, 2009 4:26 PM
panel1 and panel2 shouls move simulateneously and not one after one.
RobinMW  Tuesday, July 21, 2009 6:31 AM
panel1 and panel2 shouls move simulateneously and not one after one.


Post a corrected code snippet so that we can be on the same page.

Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 22, 2009 12:46 PM
Ok. I edited it.

Maybe I can do it myself, I just don't mind why 2 different threads with sleep s are not working simultaneously.
RobinMW  Wednesday, July 22, 2009 1:02 PM
I'm still a little grey about what I should be seeing or what your code should do.
"Move panels simultaneously" Okay, I think.

What did you edit? I still see this ...

while(true )
{
//
}

... which creates an infinite loop with no means of exiting.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 22, 2009 2:08 PM
Mm, sorry. I'm working with while(true) . I need it to check the events on the screen. One can change it with for(i<9999), for example (or I can add event for stop when some key is pressed, it's not important at the moment). It can be changed later.
Well, what should the code do. I've got 2 panels. 1 is always moving on the screen, the other moving when A or Z key is pressed (they should do that together).
But the program works like this - 1 panel is moving and when I press A or Z 1 panel is stopping and 2 is moving, when 2 is stopped, the 1 is going on.
RobinMW  Wednesday, July 22, 2009 2:21 PM
Should I see something that is reminiscent of the old video game Pong?

Your design approach is the problem. Why use separate Threads to move Form Controls on the current thread? That practice is strongly discouraged almost everywhere. It can and will cause exceptions. Putting threads to sleep is never a good thing, either.

I also have an issue with what I have where each time I click the Button causes the 1st panel to speed up.

Did you have a look at my MVC sample? As long as View's code is using the correct instance of the Controller, the Model and the View automatically update themselves.

Rudedog =8^D


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 22, 2009 4:14 PM
Yes! It should look like that game!
So you think I should put'em on one thread?
Yes, I had a look, but not quite mind it. I'm trying to get basics of MVC with OOP. I think your code is the answer, but I tried to get what's wrong with my code (for future at least, opportunities).
RobinMW  Wednesday, July 22, 2009 4:54 PM
I see no reason for separate threads at all. Threads are for long time consuming stuff.

Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, July 22, 2009 5:27 PM
Ok. Thank you very much!
RobinMW  Thursday, July 23, 2009 6:27 AM

Here's a sample that uses a backgroundworker in a not very efficient manner to move the 1st panel. The 2nd panel is not moving because you are looking for a KeyDown event on the button. Set Form.KeyPreview = true, and check the Form.KeyDown.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
//using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;


namespace WindowsApplication1
{
public partial class Form5 : Form
{
Form5 MainForm;
private Panel panel1;
private Panel panel2;
private Button button1;
private Panel panel3;


int deltax = 2;
int deltay = 2;
public delegate void MyDelegate1();
System.Threading.Thread oThread;

MyDelegate1 Delegate1;
MyDelegate1 Delegate2;

BackgroundWorker worker1;
BackgroundWorker worker2;
System.Windows.Forms.Timer timerWorker1;
object worker1Active;
//
private Button button2;

private System.ComponentModel.Container components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
this.panel3 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.AliceBlue;
this.panel1.Location = new System.Drawing.Point(21, 159);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(40, 40);
this.panel1.TabIndex = 0;
//
// panel2
//
this.panel2.BackColor = System.Drawing.Color.AliceBlue;
this.panel2.Location = new System.Drawing.Point(121, 159);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(40, 40);
this.panel2.TabIndex = 0;
//
// panel3
//
this.panel3.BackColor = System.Drawing.Color.AliceBlue;
this.panel3.Location = new System.Drawing.Point(221, 159);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(40, 40);
this.panel3.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(87, 27);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "START";
this.button1.UseVisualStyleBackColor = true;
//
// button2
//
this.button2.Location = new System.Drawing.Point(221, 27);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 2;
this.button2.Text = "STOP";
this.button2.UseVisualStyleBackColor = true;
//
// Form5
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(528, 266);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel3);
this.Name = "Form5";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

public Form5()
{
InitializeComponent();
MainForm = this;
this.Load += new EventHandler(Form1_Load);
}

void Form1_Load(object sender, EventArgs e)
{
this.button1.Click += new EventHandler(button1_Click);
this.button2.Click += new EventHandler(button2_Click);
this.Initialize_Worker1();
return;
}
void Initialize_TimerWorker1()
{
this.timerWorker1 = new System.Windows.Forms.Timer();
this.timerWorker1.Tick += new EventHandler(timerWorker1_Tick);
this.timerWorker1.Interval = 100;
}

void Initialize_Worker1()
{
this.worker1Active = false;
this.worker1 = new BackgroundWorker();
this.worker1.WorkerReportsProgress = true;
this.worker1.WorkerSupportsCancellation = true;
this.worker1.Disposed += new EventHandler(worker1_Disposed);
this.worker1.DoWork += new DoWorkEventHandler(worker1_DoWork);
this.worker1.ProgressChanged += new ProgressChangedEventHandler(worker1_ProgressChanged);
this.worker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker1_RunWorkerCompleted);
}

void worker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CheckBackgroundWorkerForException(e);

return;
}

private static void CheckBackgroundWorkerForException(RunWorkerCompletedEventArgs e)
{
if (e.Error != null) // always check BGW for thrown exception!
{
try
{
string msg_e = e.Error.Message;
}
catch (Exception ex)
{
string msg_ex = ex.Message;
}
}
}

void worker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.worker1Active = e.UserState;
PanelTopInc();
PanelLeftInc();
CalculateNextMove();
return;
}

private void CalculateNextMove()
{
if ((panel1.Top + panel1.Height + 30) >= MainForm.Height)
{
deltay = -deltay;
}
if ((panel1.Left + panel1.Width + 5) >= MainForm.Width)
{
deltax = -deltax;
}
if ((panel1.Top) <= 0)
{
deltay = -deltay;
}
if ((panel1.Left) <= 0)
{
deltax = -deltax;
}
}

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
while (!this.worker1.CancellationPending) // this loop kills main thread
{
worker1.ReportProgress(0, e.Argument);
Thread.Sleep(10); // give main thread some air.
}
return;
}

void worker1_Disposed(object sender, EventArgs e)
{
return;
}

void timerWorker1_Tick(object sender, EventArgs e)
{
this.timerWorker1.Enabled = false;
this.Initialize_Worker1();
this.worker1.RunWorkerAsync();
this.timerWorker1.Enabled = true;
return;
}

#region Original Code : PanelTopInc() :

void PanelTopInc()
{
panel1.Top += deltay;
}
#endregion
#region Original Code : PanelLeftInc() :
void PanelLeftInc()
{
panel1.Left += deltax;
}

#endregion
#region Original Code : RectMove(sender,e) :
//void RectMove(object sender, DoWorkEventArgs e)
//{


// //for (int i = 0; i < 1000; i++)
// while (true)
// {
// panel1.Invoke(Delegate1);// Top += deltay;
// panel1.Invoke(Delegate2);// Left += deltax;
// if ((panel1.Top + panel1.Height + 30) >= MainForm.Height)
// deltay = -deltay;
// if ((panel1.Left + panel1.Width + 5) >= MainForm.Width)
// deltax = -deltax;
// if ((panel1.Top) <= 0)
// deltay = -deltay;
// if ((panel1.Left) <= 0)
// deltax = -deltax;

// System.Threading.Thread.Sleep(10);
// }
//}

#endregion
#region Original Code : void RectMove() :
//void RectMove()
//{
// this.RectMove(new object(), new DoWorkEventArgs(new object()));
//}

#endregion

private void button1_Click(object sender, EventArgs e)
{
#region Original Code : Content :

//Delegate1 = new MyDelegate1(PanelTopInc);
//Delegate2 = new MyDelegate1(PanelLeftInc);
////
////oThread = new System.Threading.Thread(new System.Threading.ThreadStart(RectMove));
//ThreadStart threadStarter = new ThreadStart(RectMove);
//oThread = new Thread(threadStarter);
////
//oThread.Priority = System.Threading.ThreadPriority.Highest;
//oThread.Start();
#endregion
if (!this.worker1.IsBusy)
{
this.Initialize_Worker1();
this.worker1Active = new object();
this.worker1.RunWorkerAsync(this.worker1Active);
}

}
private void button2_Click(object sender, EventArgs e)
{
if (!this.worker1.CancellationPending)
{
this.worker1.CancelAsync();
}
}

#region Original Code : Panel2TopInc() :
//void Panel2TopInc()
//{
// for (int i = 0; i < 20; i++)
// {
// panel2.Top -= 2;
// System.Threading.Thread.Sleep(20);
// }
//}
#endregion
#region Original Code : Panel2TopDec() :

//void Panel2TopDec()
//{
// for (int i = 0; i < 20; i++)
// {
// panel2.Top += 2;
// System.Threading.Thread.Sleep(20);
// }
//}
#endregion
#region Original Code : Panel2Top1() :

//void Panel2Top1()
//{
// MyDelegate1 MyDelegate = new MyDelegate1(Panel2TopInc);
// panel2.Invoke(MyDelegate);
//}
#endregion
#region Original Code : Panel2Top2() :

//void Panel2Top2()
//{
// MyDelegate1 MyDelegate = new MyDelegate1(Panel2TopDec);
// panel2.Invoke(MyDelegate);
//}
#endregion
#region Original Code : button1_KeyDown(sender, e) :

//private void button1_KeyDown(object sender, KeyEventArgs e)
//{
// System.Threading.Thread oThread1 = new System.Threading.Thread(new System.Threading.ThreadStart(Panel2Top1));
// System.Threading.Thread oThread2 = new System.Threading.Thread(new System.Threading.ThreadStart(Panel2Top2));


// if (e.KeyData == Keys.A)
// oThread1.Start();
// if (e.KeyData == Keys.Z)
// oThread2.Start();
//}
#endregion

}
}
}


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Thursday, July 23, 2009 12:44 PM

You can use google to search for other answers

Custom Search

More Threads

• Highlighting row in DataGrid
• Filtering Null values
• length of an object name in vb.net
• How to get selected folder or file name in WindowsExplorer by using c#.net?
• Automating Outlook Send/Receive Using C#
• Validating a user with a Login Form
• Unicode Handling
• Help assigning random images to Picturebox's
• Changing a property of a dynamically added control
• Possible to "spin off" the GUI thread? (Not halting the system at Application.Run)