Adam Volker-Yoblick

Greetings,

I am writing an application that I want to be able to use through the console as well as through a form. My application is set up to start up a form if there are no arguments on the command line, and to run in a console window if any arguments exist.

My problem is that my form doesn't seem to be updating correctly since the application is set up as a console app. I remember reading about message pumping, but I didn't fully understand it.

Do I have to do manual message pumping to update my main form if the application is a console app If so, what's the recommended way to do this

Thanks!



Re: Windows Forms General How can I run a Winform within a console application?

Peter Ritchie

You need a call to Application.Run with a form you want displayed.




Re: Windows Forms General How can I run a Winform within a console application?

Adam Volker-Yoblick

Maybe I wasn't clear with my question. =)

I'm aware of the need to call Application.Run(myForm). However, when I'm running as a console application, the form does not seem to be updating properly. When I make the app a "Windows Application" (in the project properties) the form runs fine.

I have a feeling that this has to do with the automatic message pumping that takes place when your application is a Windows App, but I'm not 100% sure. I wanted to know if anyone has run into a similar issue, or have other people been able to run a WinForm (with workers in background threads) with no problems through a console app





Re: Windows Forms General How can I run a Winform within a console application?

Peter Ritchie

There's no automatic message pumping, Application.Run is the message pump. You're running Application.Run(myForm) and *still* having problems How many forms are any other forms created outside of Application.Run (i.e. not from events from another form)




Re: Windows Forms General How can I run a Winform within a console application?

Adam Volker-Yoblick

There's one more form, which is an options form, but I pass it to the main form as an argument. I think I was running into some issues related to something else.

I'm going to fix a couple things in my app and try it in console mode, and I'll re-post if I continue to have issues.

Thanks!





Re: Windows Forms General How can I run a Winform within a console application?

Peter Ritchie

How are you passing the options form to the main form something like this

Code Snippet

OptionsForm optionsForm = new OptionsForm();

MainForm mainForm = new MainForm(optionsForm);

Application.Run(mainForm);

If so, what are you doing in the MainForm constructor with the optionsForm argument Anything you do in there will be done before the message pump has started up...






Re: Windows Forms General How can I run a Winform within a console application?

Peter Ritchie

Peter Ritchie wrote:

How are you passing the options form to the main form something like this

Code Snippet

OptionsForm optionsForm = new OptionsForm();

MainForm mainForm = new MainForm(optionsForm);

Application.Run(mainForm);

If so, what are you doing in the MainForm constructor with the optionsForm argument Anything you do in there will be done before the message pump has started up...

I tried a quick sample of a console application that shows a form with an second form (shown by clicking a button) like the sample code I provided and do not get any update problems.

Maybe you can describe the update problems you're encountering.






Re: Windows Forms General How can I run a Winform within a console application?

Adam Volker-Yoblick

Well, I was running into an issue where I needed to wait for worker threads in a Deployer class to finish before I exited my program, so I had my main thread sleep and wait for a Thread.Interrupt, but since I was using winforms, the main thread sleeping meant the UI was not updating. I thought this happened when I changed the application to run as a "console application," but I think I was mistaken.

I'll re-post again if I run into any more issues =)





Re: Windows Forms General How can I run a Winform within a console application?

Adam Volker-Yoblick

Actually, I'm still running into the problem.

Here's the issue: in my main(), I check to see if there are any arguments. If there are no arguments, I instantiate the form and run it. So far, this is working with no problems.

If there ARE arguments, I instantiate another class to do some work as a console app. The problem is that the work will be done on worker threads which are different from the main application thread, so I need to make the man thread go to sleep while waiting for output from the worker threads. If the main thread does not sleep, it will exit, which will kill the worker threads.

I wanted to know the best way to do this. I had something like this in mind:

Thread mainThread = Thread.CurrentThread;

workerThread.RunWorkerCompleted += WorkDone;

// after worker threads are started

bool areWorkersRunning = true;

while (areWorkersRunning)

{

Try

{

curThread.Sleep(someArbitraryTime);

}

catch (ThreadInterruptedException)

{

areWorkersRunning = false;

// do cleanup and end the main program

}

}

void WorkDone(object sender, RunWorkerCompletedEventArgs e)

{

mainThread.Interrupt();

}

Is there a better way to get this done

Thanks





Re: Windows Forms General How can I run a Winform within a console application?

Peter Ritchie

Adam Volker-Yoblick wrote:

Actually, I'm still running into the problem.

Here's the issue: in my main(), I check to see if there are any arguments. If there are no arguments, I instantiate the form and run it. So far, this is working with no problems.

If there ARE arguments, I instantiate another class to do some work as a console app. The problem is that the work will be done on worker threads which are different from the main application thread, so I need to make the man thread go to sleep while waiting for output from the worker threads. If the main thread does not sleep, it will exit, which will kill the worker threads.

I wanted to know the best way to do this. I had something like this in mind:

Thread mainThread = Thread.CurrentThread;

workerThread.RunWorkerCompleted += WorkDone;

// after worker threads are started

bool areWorkersRunning = true;

while (areWorkersRunning)

{

Try

{

curThread.Sleep(someArbitraryTime);

}

catch (ThreadInterruptedException)

{

areWorkersRunning = false;

// do cleanup and end the main program

}

}

void WorkDone(object sender, RunWorkerCompletedEventArgs e)

{

mainThread.Interrupt();

}

Is there a better way to get this done

I would recommend using an event instead of mainThread.Interrupt. You end up having to be in a loop wasting cycles "polling"; plus the Sleep (as you've described the parameter) is arbitrary and means you thread is guarenteed to sleep for at least x milliseconds. If x is 250 milliseconds and WorkDone is called 1 millisecond after Sleep is called your app is "hung" for about 250 milliseconds until the next poll. Plus, I view Interrupt as using Exceptions for normal logic.

Something like:

Code Snippet

static EventWaitHandle manualEvent = new ManualResetEvent(false);
static void Main()
{
//...

workerThread.RunWorkerCompleted += worker_WorkDone;

workerThread.RunWorkerAsync(/*parameters */);


// wait for backgroundworker
manualEvent.WaitOne();
}
public static void worker_WorkDone(object sender, RunWorkerCompletedEventArgs e)
{
// only if in Conosole mode
manualEvent.Set();
}