Multithreading, Windows Forms vs Console Apps

M

MeowCow

I will try and make my question with out being too long winded. I have
been doing a lot of reading on how to do multithreading and I have
implemented the code from the following example on codeproject and
msdn.

http://www.codeproject.com/csharp/LaunchProcess.asp
http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx

In the eample Standard out is read like this:

void ReadStdOut()
{
string str;
while ((str = process.StandardOutput.ReadLine()) != null)
{
FireAsync(StdOutReceived, this, new
DataReceivedEventArgs(str));
}
}

The reason for this is because ReadStdOut is in a separate thread. And
then FireAsync Calls methods registered on the UI Thread to the
StdOutRecieved delegate.

This works great if I am running a Windows Forms app and I can pass a
control into the contructor of ProcessCaller. Then FixAsync just uses
the controls BeginInvoke method to call back to the UIThread.

My Question is, If I want this to work for a console app as well will
the events get to the proper Main thread if I just fire the delegate
instead of using BeginInvoke? There are no controls in the Console
App, so I don't have a BeginInvoke call.

Please let me know if I can clairify any of this.
Thanks for your help

Adam dR.
 
J

Jon Skeet [C# MVP]

My Question is, If I want this to work for a console app as well will
the events get to the proper Main thread if I just fire the delegate
instead of using BeginInvoke? There are no controls in the Console
App, so I don't have a BeginInvoke call.

Yes, Console.WriteLine is threadsafe, so you can write it synchronously
in your reading thread.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


My Question is, If I want this to work for a console app as well will
the events get to the proper Main thread if I just fire the delegate
instead of using BeginInvoke? There are no controls in the Console
App, so I don't have a BeginInvoke call.

Hi, I'm not very clear of where your problem is, for you to force an event
to be handled in a given thread that thread implements a message pump from
where it's constantly checking to see if there is a message waiting.

cheers,
 
M

MeowCow

Okay let me explain this another way.

ProcessCaller Constructor:
public ProcessCaller(ISynchronizeInvoke isi);

This constructor takes an ISynchronizeInvoke (aka a Control) The
control is used to by the FireAsync method above to Fire the
StdOutRecievd Event on the UIThread. (NOTE all of this works fine)

processCaller = new ProcessCaller(this);
processCaller.StdOutReceived += new
DataReceivedHandler(writeStreamInfo);
processCaller.Start();

What I would like to do is make this ProcessCaller work for both
Windows Forms Apps and Console apps. But I don't have a control to
pass to the constructor of Process Caller.

This is the original FireAsync used to return event to the UIThread
from a working thread. Target is the ISynchronizeInvoke isi passed
into the constructor.

protected void FireAsync(Delegate dlg, params object[] pList)
{
if (dlg != null)
{
if (Target != null)
{
Target.BeginInvoke(dlg, pList);
}
}
}

What I would like to do is:
protected void FireAsync(Delegate dlg, params object[] pList)
{
if (dlg != null)
{
if (Target != null)
{
Target.BeginInvoke(dlg, pList);
}
else
{
dlg(pList[0], pList[1]);
}
}
}

This way I can Create a new ProcessCaller() with no ISynchronizeInvoke
object. My question is, If I am in a console application and this code
is in the main thread

processCaller = new ProcessCaller();
processCaller.StdOutReceived += new
DataReceivedHandler(writeStreamInfo);
processCaller.Start();

and the call to fire the StdOutRecieved Delegate is in a worker thread.
Is the event guarenteed to get back to my main thread and call
writeStreamInfo even though the delegate is called from the worker
thread?
 
W

Willy Denoyette [MVP]

Okay let me explain this another way.

ProcessCaller Constructor:
public ProcessCaller(ISynchronizeInvoke isi);

This constructor takes an ISynchronizeInvoke (aka a Control) The
control is used to by the FireAsync method above to Fire the
StdOutRecievd Event on the UIThread. (NOTE all of this works fine)

processCaller = new ProcessCaller(this);
processCaller.StdOutReceived += new
DataReceivedHandler(writeStreamInfo);
processCaller.Start();

What I would like to do is make this ProcessCaller work for both
Windows Forms Apps and Console apps. But I don't have a control to
pass to the constructor of Process Caller.

This is the original FireAsync used to return event to the UIThread
from a working thread. Target is the ISynchronizeInvoke isi passed
into the constructor.

protected void FireAsync(Delegate dlg, params object[] pList)
{
if (dlg != null)
{
if (Target != null)
{
Target.BeginInvoke(dlg, pList);
}
}
}

What I would like to do is:
protected void FireAsync(Delegate dlg, params object[] pList)
{
if (dlg != null)
{
if (Target != null)
{
Target.BeginInvoke(dlg, pList);
}
else
{
dlg(pList[0], pList[1]);
}
}
}

This way I can Create a new ProcessCaller() with no ISynchronizeInvoke
object. My question is, If I am in a console application and this code
is in the main thread

processCaller = new ProcessCaller();
processCaller.StdOutReceived += new
DataReceivedHandler(writeStreamInfo);
processCaller.Start();

and the call to fire the StdOutRecieved Delegate is in a worker thread.
Is the event guarenteed to get back to my main thread and call
writeStreamInfo even though the delegate is called from the worker
thread?

The delegate target (writeStreamInfo) will run on the worker thread, not on
your "main" thread.
Is there any reason you want this to happen, is there anything in
writeStreamInfo that has thread affinity?
The only reason you have to delegate the target to run on the "main" thread
in an GUI based application is that you may not read/update the UI from
another thread than the thread that created the UI element(s).
Or otherwise stated - Windows UI elements (basically HWND's) have thread
affinity, your console application doesn't touch Windows UI elements, so you
can update the "console" from any thread in the process (unless you are
using objects that have thread affinity, but I assume you don't).

Willy.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,
and the call to fire the StdOutRecieved Delegate is in a worker thread.
Is the event guarenteed to get back to my main thread and call
writeStreamInfo even though the delegate is called from the worker
thread?

What does writeStreamInfo do that is SO important for you to run in the main
thread?
In a win app this is important, it not the same in a console app.

cheers,
 
M

MeowCow

Hey Guys thanks a lot. I get it now. writeStreamInfo won't have any
code that isn't thread safe, on the console application so it should
work just fine. For some reason I thought I had to get the event back
to the main thread. Everything makes sence now. Just learning
threading and this helped a lot, I appreciate it!!!

~Adam dR.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top