Click here to Skip to main content
15,894,540 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello, This is probably an easy question for most to answer but I am new to C# programming and am not used to the formatting. Unfortunately, for what I am trying to do I believe C# will be the best approach.

The overall goal is to have a front end (GUI via WinForms) that with a click of a button I can start or stop a service on a remote desktop. The issue I have run into is getting threading to work and passing the name of the location of the desktop back to the thread in a different class.

Below is my code in a generalized fashion. The section I am having difficulty with is within the button4_Click. The text on each button would represent the location of the service I am starting or stopping which is why it is ideal to use it as the property passed to the TS_Start function.

Maybe I am going about this all wrong, any input would be great! Thanks!

C#
namespace Phoenix
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>

        public string Start = "Attempting to start ";
        public string Stop = "Attempting to stop ";
        public static TimeSpan timer1 = new TimeSpan(0, 2, 0);

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
		
        public static void GEN_Start(string location)
        {
            ServiceController svc = new ServiceController("Service Name", location);
            svc.Start();
            svc.WaitForStatus(ServiceControllerStatus.Running, timer1);
            if (svc.Status == ServiceControllerStatus.Running)
            {
				// Service Running do stuff
            }
            else
            {
				// Service not Running do stuff or time-out
            }
        }
    }
	
	public partial class Form1 : Form
    {
        public Form1()
        {
            ConnectionOptions options = new ConnectionOptions();
            options.Password = "username";
            options.Username = "password";
            InitializeComponent();
        }
		private void button4_Click(object sender, EventArgs e)
        {
			// Check if user is sure
            Form2 frm = new Form2();
            DialogResult result = frm.ShowDialog();
            if (result == DialogResult.Yes)
            {
				// Start thread
                Thread START=new Thread(new ThreadStart(Program.GEN_Start(button4.Text)));
                START.Start(button4.Text);
            }
        }
	}

	public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // YES
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // NO
        }
    }	
}
Posted
Comments
BillWoodruff 15-Dec-15 22:53pm    
"The section I am having difficulty with is within the button4_Click." Are you getting an error message now ? Please describe the "difficulty" clearly.

1 solution

There is a number of aspects of passing data between threads. First important aspect is passing notifications from a non-UI thread to, specifically, to a UI thread. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
.NET event on main thread,
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading.

See also the reference in my other answer: .NET event on main thread[^].

Note the reference above related to blocking collection (Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^]). The invocation mechanism I explained above is implemented only for the UI frameworks/libraries. It is inapplicable to some arbitrary threads; you would need to create a similar mechanism. My article of blocking collection explains it, and an alternative solution to mine recommends existing .NET BCL class System.Collections.Concurrent.BlockingCollection.

Other aspects of passing data in asynchronous way, especially at thread initialization (but not only), are covered by the technique of thread wrappers I put forward. Please see my past answers:
Making Code Thread Safe[^],
How to pass ref parameter to the thread[^],
Change parameters of thread (producer) after it is started[^],
MultiThreading in C#[^].

—SA
 
Share this answer
 
v2
Comments
BillWoodruff 15-Dec-15 21:47pm    
+5 very clear, very useful

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900