C# - Application.Run() - c#

I am just starting .Net development (C#) and have come across some code that has me slightly confused....
If I have
Form myForm = new Form();
What does the following line actually do:
Application.Run(myForm);
Does it essentially do the same thing as myForm.ShowDialog() or myForm.Show() (that's what I thought, when running a form will do).....
I always find that the msdn is a poor resource for properly explaining material to new comers

Application.Run(myForm); makes that form visible to user. It is the first form which get loaded in memory. And it runs this form in a message loop, so that you get all user events.
Short Answer:
Application.Run begins running a standard application message loop on the current thread.
Long Answer:
Application.Run causes the windows application enters the message loop within Winmain to process various windows messages the OS posts to a message queue.The message loop, "Loops" until its receives a WM_QUIT message. It uses GetMessage and PeekMessage to retrive messages and PostMessage to sent the retrived messages to Windows procedure.
If you do
Form myForm = new Form();
myForm.Show();
it will show the form and exit out. You will use new Form() & .Show() when you want to launch a new form from existing form.
Hope this answers your question.

to start an application with a main form, so that the application terminates when the main form is closed. it will be associated to the current thread. it runs this form in a message loop.
Message Loop means : They act upon messages that the operating system posts to the main thread of the application. These messages are received from the message queue by the application by repeatedly calling the GetMessage (PeekMessage) function in a section of code called the "event loop."
Application Run()

Related

Windows form controlled by main loop

How can I control windows form class in the main loop?
Can I still run my code in the main loop like a console program but use windows form to display stuff? I already done that I've got windows form application and console in one but once main calls windows form that's it, it doesn't come back to main.
Can I pass variables to windows form?
You can't.
When you call Application.Run, the method only returns when there is no active Form any more. This is because Application.Run keeps the message loop running. It blocks the current method form returning. See it as a while (mainFormActive). It will never end unless the main form is closed.
If you want to execute code in the mean time, set up a Task, a Thread or similar, before you start the form.
And yes, you can pass variables in, just like in any constructor.

Having two active windows in a Winform application

Sorry, this more than likely has been asked at some point but I'm not even sure what I should be searching on...
I have a winform application with multiple forms. Up until this point having a one form open at a time has been fine. But now, I have a new form that I want to add on but have the ability to keep that form open while I work in other forms. I'm not even sure what this is called but I have seen it done before in other applications.
I did find this: Run two winform windows simultaneously
But this new window is a winpipe queue viewer that runs a thread. When I try initializing using the
Application.Run(new QueueViewer());
I get the error:Starting a second message loop on a single thread is not a valid operation. Use the Form.ShowDialog instead.
The problem with that is it locks the program from doing anything else until I close that form.
Thanks for your help!
Add a form to your project (let's call it Form2). Somewhere within your code (maybe in a button click event) use the following code:
Form2 f = new Form2();
f.Show();
The Show method allows you to interact with the originating form, whereas ShowDialog prevents interaction from the original form.

Dialog hangs when called from event

Using the CoreScanner Driver provided by Motorola, I'm trying to write a small winforms application that uses a barcode scanner. I'm able to interact with the scanner just fine, and properly register a call back for the OnBarcodeEvent(). In this callback, I have a Dialog that opens and displays a screen that the user needs to fill in. Shortly after the dialog is opened (using Show()), the program hangs. If I use ShowDialog(), the dialog works, but the dialog is blocking the OnBarcodeEvent event.
My guess to what is happening, is that since the dialog is getting created on the event thread, there is a race condition occurring when using Show(). Since Show() is non-blocking, the thread continues on after displaying the dialog and then dies out. Meanwhile my dialog just lost it's parent and locks up? Like i said... my best guess.
How can I remedy the situation? That is, How do I write my dialog so that it can be created within a thread not hang?
In the event, you should launch a different thread that will create your dialog form and show the form on it. You need to block this thread till form is visible - this is possible either by ShowDialog or alternately use one of Application.Run overload.
Yet another option would be to show the form on the UI thread (i.e. main application thread) - to do that, you need to call Invoke method on your main form from the event code. The invoke call should take the delegate that will show your dialog form non modally.
I have some experience with Motorola/Symbol Handheld-Devices (MC9090) and I guess the SDK will be similar.
It's hard to say without seeing the code, but my guesses:
your common not-UI thread problem - so make sure you open your dialog using UI thread
the native Motorola-driver is crashing - no kidding, this happened a lot to me - in my case (compact-framework on a WinCE device) this would not freeze the program but the scanner will not work/receive any messages before restarting the device
In order to fix this you should seperate the showing/handling of user-dialog away from the event and make sure you call this on the UI-thread (Control.InvokeRequired / Control.Invoke).

Blocking function call

I am writing a small test application to test a communication interface. The communication interface is written in C++ (a DLL) and the test application using C#. The communication interface in turn talks to a low level hardware stack which uses windows messages to transmit and receive data. In order to achieve this, the commuication interface DLL creates an invisible child window whose parent is the C# test application window. The sequence to talk to the hardware is as follows :
Initialize the communication library. This step expects the main window handle and application instance which is passed to the low level stack for windows messaging.
Connect using the device address
Read/Write
Close
Deinitialize the communication library.
Now in the 2nd step, the DLL creates an invisible window to communicate with the low level hardware stack. Since the 2nd step is a blocking call, I want my UI to be responsive during this time in case it takes a long time to connect. Therefore, I try to connect asynchronously using a thread or a BeginInvoke call. But I observe that after the connection is established, the application window hangs as long as the child window exists. The child window seems to block all incoming messages to the main window. This seems to be because the child window gets created in another thread.
But I dont want want the connect to be in the main thread as it hangs the UI.
I would welcome any ideas on how to avoid this problem ? Thanks in advance.
-Harish
All communication with a window handle must be done on the thread this handle was created on. This probably means that all calls to the DLL should be done on the secondary thread.
You can try the following:
Before initializing the DLL, start a background thread;
On that thread, create a WinForms window you do not show. You can do this like this:
-
public static Form BackgroundForm;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new Thread(new ThreadStart(Secondary)).Start();
Application.Run(new MainForm());
}
static void Secondary()
{
BackgroundForm = new Form();
// Calling Handle creates the system HWND. You do not have to call Show
// or something similar on this Form to make the handle available or use
// Invoke or BeginInvoke.
var handle = BackgroundForm.Handle;
// Initialize the DLL here with the handle.
Application.Run();
// Unintialize the DLL.
}
Then, initialize the DLL with the handle you got from the background form;
When you need to do calls to the DLL, do this using Invoke and BeginInvoke to this background form;
Once it's time to shut down your application, do an Application.ExitThread() through a Invoke or BeginInvoke.
The problem you are seeing with the main form being blocked, is probably because the child window created in the DLL has the main form's handle as it's parent Window, but that's just a guess. This should probably also be solved using this system.

What Application.Run( ) does?

I was thinking that WinForms are classes as any other classes. But starting form project get me confuse. Why new Form start with Application.Run and what kind of mechanism happen inside of it ?
As it says in the documentation, it begins running a standard application message loop on the current thread. The message loop handles clicks, keypresses, paint requests, plus many other things.
When called with a form as an argument it also makes that form visible.
This goes way back to the Win32 API. Winforms sits on top the win32 api. Application.Run() plugs your program into (implements) the win32 message loop. Pretty much all mouse and keyboard events (and most anything else initiated by the user) are really win32 messages.

Categories