12

FURTHER EDIT the following is not production code - I'm just playing around with a couple of classes trying to figure out how I run processes within threads - or even if that is viable. I've read various definitions on MSDN but am a newbie to threads and processes so any further definitive references to articles would be appreciated


this is fine...

class Program {
    static void Main(string[] args) {

        Notepad np = new Notepad();
        Thread th = new Thread(new ThreadStart(np.startNPprocess));
        th.Start();

        Console.WriteLine("press [enter] to exit");
        Console.ReadLine();
    }
}

public class Notepad {

    public void startNPprocess() {

        Process pr = new Process();
        ProcessStartInfo prs = new ProcessStartInfo();
        prs.FileName = @"notepad.exe";
        pr.StartInfo = prs;
        pr.Start();     

    }
}

this isn't...

class Program {
    static void Main(string[] args) {


        Process pr = new Process();
        ProcessStartInfo prs = new ProcessStartInfo();
        prs.FileName = @"notepad.exe";
        pr.StartInfo = prs;

        ThreadStart ths = new ThreadStart(pr.Start);
        Thread th = new Thread(ths);
        th.Start();


        Console.WriteLine("press [enter] to exit");
        Console.ReadLine();
    }
}

Why does the second not do the same as the first? In the second script I'm trying to pass Process.Start using the Threadstart delegate ...I thought this would be ok as its a void method? Is the first script the only option or can I change the second slightly so that it effectively does the same job as the first i.e start an instance of Notepad in a specified thread?


EDIT

Some background as to why I'm playing around with this code: ultimately I need to build an application which will be running several Excel processes simultaneously. These processes can be troublesome when VBA errors as it results in a dialogbox. So I thought if each process was running in a thread then if a particular thread has been running for too long then I could kill the thread. I'm a newbie to Threads/Processes so basically playing around with possibilities at the moment.

whytheq
  • 34,466
  • 65
  • 172
  • 267
  • 4
    What is the benefits of starting a process from another thread? Why don't you simply starts the process from the current Thread? The result will be the same, as starting a process won't wait for its completion. – Steve B Jan 22 '13 at 09:46
  • 2
    Process.Start is not a void method, it returns bool. – Chris McAtackney Jan 22 '13 at 09:49
  • Concerning your edit, shouldn't you automate Excel using COM (or better, not using excel at all using open xml SDK), instead of starting a new process? – Steve B Jan 22 '13 at 10:24
  • Or just not automate Excel ... http://support.microsoft.com/kb/257757 (yes it's for server-side stuff, but it seems applicable here) – ta.speot.is Jan 22 '13 at 10:25
  • this is a comment to your edit, you can disable most dialogs in excel, so they don't popup, unless you want them to – Henrik Bøgelund Lavstsen Jan 22 '13 at 10:31
  • @HenrikBøgelundLavstsen the VBA error such as Run Time error is more difficult ... if I've run the VBA macro via a `.NET` process and there is a VBA run-time error then its difficult to get rid of the dialog box as its difficult for .NET to know that an error occured: `TRY-CATCH` using Excel-Interop does not catch these errors – whytheq Jan 22 '13 at 10:36
  • @SteveB I'm using a mixture of Excel Interop automation in `.NET` and `VBA` embedded in the Excel files ....some of the `VBA` routines are extensive and I'm unwilling to move all that code to `C#` – whytheq Jan 22 '13 at 10:38
  • @TomTom rather than the sarcy comment how about a link to a definitive MSDN page that will help: I'm a newbie to writing multi-process / multithreaded code so a comment with a `;)` doesn't really help – whytheq Jan 22 '13 at 10:39
  • @whytheq But i don't get why you want to open it with a process, if you open it by initiating a excel object it will start the application in the background, atleast with c#, and i would assume it would happen with vba aswell. – Henrik Bøgelund Lavstsen Jan 22 '13 at 10:42
  • @HenrikBøgelundLavstsen how does this information help if there is a VBA runtime error? – whytheq Jan 22 '13 at 11:33

5 Answers5

28

A ThreadStart expects a delegate that returns void. Process.Start returns bool, so is not a compatible signature. You can swallow the return value in by using a lambda that gives you a delegate of the correct return type (i.e. void) as follows:

    Process pr = new Process();
    ProcessStartInfo prs = new ProcessStartInfo();
    prs.FileName = @"notepad.exe";
    pr.StartInfo = prs;

    ThreadStart ths = new ThreadStart(() => pr.Start());
    Thread th = new Thread(ths);
    th.Start();

...but it's probably advisable to check the return value:

    ThreadStart ths = new ThreadStart(() => {
        bool ret = pr.Start();
        //is ret what you expect it to be....
    });

Of course, a process starts in a new process (a completely separate bunch of threads), so starting it on a thread is completely pointless.

spender
  • 117,338
  • 33
  • 229
  • 351
  • 3
    Downvoter, please explain what you believe to be problematic with this answer so I can improve it. – spender Jan 22 '13 at 09:54
  • +1 @Spender thanks for spending the time on this - my OP is currently -3...seems to be a few keen anonymous downvoters out there! – whytheq Jan 22 '13 at 10:18
  • 6
    cool this was the line I needed! ...`Of course, a process starts in a new process (a completely separate bunch of threads), so starting it on a thread is completely pointless.` – whytheq Jan 29 '13 at 12:50
  • 7
    its not pointless if my thread is a telnet process and I need to read the output while my other app doesnt get blocked. If I start the process wait for text...but still need to send commands and wait for more responses, it just blocks because the telnet never ends the process. So starting in another thread and delegating the output from the other process thread, down through my thread to the client, makes sense, until i explicitly call exit, killing both threads. but.. is that the correct way to do it.. no idea. MS call it interactive protocol Processes but no example how to handle it. – Piotr Kula Feb 26 '15 at 14:44
  • Not sure if this above entirely correct. from msdn "A processor executes threads, not processes, so each application has at least one process, and a process always has at least one thread of execution, known as the primary thread." – Pawel Dubiel Jan 31 '20 at 17:04
7

you can make changes like

ThreadStart ths = new ThreadStart(delegate() { pr.Start(); });
4

Just start the process normally using this code:

Process.Start("notepad.exe");

There is no point and no benefits in creating a thread to run a new process. It's like running a batch file that executes "cmd.exe" when you can directly execute "cmd.exe"... you are just doing more than what's necessary for nothing. Don't reinvent the wheel and play easy :P

Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98
  • +1 thanks for the help; seemed like quite a few didn't appreciate my question - currently -3 ! – whytheq Jan 22 '13 at 10:22
  • the benefit of this code is that I'm playing around with these classes trying to understand what they do - this is not production code - I'm just trying to figure out how I run processes within threads - or if I can? – whytheq Jan 22 '13 at 10:41
  • Of course you can. But if you ask me if it's good I will answer no. It makes no sense. Threads are good for running application code, not external processes. – Tommaso Belluzzo Jan 22 '13 at 10:46
4

Not answering directly the OP, but as this thread helped me track the right direction, I do want to answer this:

"starting it on a thread is completely pointless"

I have a .Net server that uses NodeJS as its TCP socket manager. I wanted the NodeJS to write to the same output as the .Net server and they both run in parallel. So opening in a new thread allowed me to use

processNodeJS.BeginErrorReadLine()
processNodeJS.BeginOutputReadLine()
processNodeJS.WaitForExit()

while not blocking the main thread of the .Net server.

I hope it makes sense to someone and if you have a better way to implement what I've just described, I'll be more than happy to hear.

Qua285
  • 137
  • 1
  • 3
  • 12
1

You can start the process in another thread by using the start keyword like below this cod:

Process.Start("start notepad.exe");

in this way, your GUI program doesn't freeze when you run the notepad.

Ahad aghapour
  • 2,453
  • 1
  • 24
  • 33