just curious on others' take on this... I use apps hungarian to indicate if the parameter will be passed as Ref or Out since VBA does not really help with the distinction.
Public Function Validate(OutMessage As String) As Boolean
End Function
Public Sub UseIt()
Dim Message As String
If Not Validate(Message) Then
End If
End Sub
Question: would you change the code Dim Message As String to Dim OutMessage As String to make it more explicit? Or would you just use OutMessage:=Message ?
* .Wait() clogs the UI thread and the ProgressBar can't update.
* I async/await it instead, and follow the viral spread upward.
* When I make Main() async, it complains that WPF requires STAThread for UI components even though Main() is already marked as STAThread, because that gets overridden/ignored by async.
* When I make a new thread for main and set its ApartmentState to STA, it says I need to make my lambda expression async to be able to await inside of the thread's task.
I stopped there because I worried I was going completely off the rails.
@this Why do I want a WaitForAll() for one containing task, and would WaitForAll() offload from the UI thread? From my homework this weekend, I'm of the impression that any kind of wait on the UI thread keeps it busy.
Won't the containing task only be marked completed when all the Parallel.For is done? Or did I misunderstand?
the idea is that you want to start each task off async. Then you use WaitAll() to get all tasks result before you continue.
the thread that WaitAll has to be non-UI thread, too; you probably want to disable the Run button (or whatever it is), and enable it only when the WaitAll() has returned.
Okay, I'll look at that. I do understand what WaitAll() does, but maybe by looking at that code I'll be able to answer my own questions about why I'd need WaitAll instead for what seems to be a single task.
But the thread that starts other tasks itself needs to be non-UI thread so you end up with one task that basically acts as the synchronizer for all tasks in parallel.
Right. You don't want your UI thread to be busy, even if you have no button. It should just be idle, listening for events from all tasks, including the task doing the synchronization.
@this Okay, listening for events from all tasks in the form of await, right?
If so, then are you confirming I need to have an async main and to kick things off with with a new thread marked STA with an async lambda expression? Or did I miss an exit on the highway to Crazytown before that?
class Entry
{
[STAThread]
static void Main()
{
try
{
var programCompleted = false;
var landing = new Landing();
while (!programCompleted)
{
landing.ShowDialog();
if (!landing.GoToNextWindow) { return; }
while (landing.GoToNextWindow)
{
switch (landing.ChosenUtility)
{
For all of my windows, they show up, the user clicks something, and then they close and work continues (on the UI thread because I'm still struggling to get if off) or another window is put up in response.
So on that landing window, they are just picking which tool they want to use, and landing quickly saves their choice to a property and marks whether they hit exit or not and goes from there.
Back from a mandated restart and you are correct, I don't have any dispatchers in my code. If I understood Mat correctly, I won't need them as long as my UI updates are data-bound.
(The UI does display the correct update after the program is over)
@puzzlepiece87 from the UI thread, don't do any waiting or awaiting. You would do something like this:
Task.Run(()=> ParallelProcessFiles());
Where that Parallel.For now lives in it's own Async procedure, outside of the UI code. Preferably in a different module where all of your action code lives.
The UI just goes back to normal. If you need some action to happen at the end it needs to be called from the end of your ParallelProcessFiles procedure, not the UI thread. You would raise a signal to the UI thread that the process is done.
@HackSlash Okay, I'll try that again. In my memory, if I don't wait/await for the tasks to be done, the program finishes execution. I'm a little unclear how to keep it listening as you two are describing.
In my memory, when I kicked off the ParallelFileProcessing without awaiting, it gave control back to the caller, Main() basically, and the program ended.
Because there were no other steps left in Main() to execute
@puzzlepiece87 ok, now I'm confused. You said "UI Thread" before but now you are describing the behavior of a console application. The program flow is going to be different depending on if you are making a windows forms application or a console application. So which is it?
I've never done that. Normally, there is an idle loop that is handled by a WinForms application. From a Console application I'm not sure if you can pass off to the form or if you have to manually create your own idle loop. Sounds like a bad idea. There is a thread here that is full of bad ideas: stackoverflow.com/questions/277771/…
Note: I have made Forms/WPF applications that can be invoked from the command line and produce output to the console window. They are still defined as GUI applications and they don't have the problems you are experiencing.
The graphics are just for user configuration and progress display
I just finished taking command line stuff out actually
I can't maintain it as a sole developer, too little use so far
@HackSlash I'm almost certainly doing something really dumb.
Like misunderstanding the basics of offloading or something.
I'll get it eventually.
Right now I'm trying to follow up on what you two told me today by finding the very first command after the GUI is done (except the progress bar) and Tasking out from there instead.
Read your thread, misspoke in calling my program a console app because I don't use a console. What I actually meant is that all the work is being done largely independently of any kind of graphical interaction.