Still not getting it Threads_ services_ etc

Topics: CAB & Smart Client Software Factory
Mar 1, 2006 at 10:05 AM
originally posted by: sklett

I've been looking through the Appraiser's app trying to find a pattern that fits the general structure of my application. After spending 1.5 hours I find myself more confused on how to proceed. While I can appreciate the apparent flexibility of the Appraiser app, It's so decoupled that I can't see the flow of the application.

In other words, I'm confused.

I know I ask a lot of questions here and everyone has been real helpful and I appreciate it. I'm not ready to give up, but I do need just a bit of help with a particular scenario.

I have a module with a single view (at this time) it lists files that can be programmed to an embedded device via an attached piece of hardware.
The basic idea is that a user double clicks a file in the list and this would start the process.
I have it setup right now so the View handles the double click event, publishes (is that the correct term or is it 'fires') an even via EventBroker.
In my root WorkItem I have a subscription to this event. This event handler then makes calls on a static class that controls the attached hardware programmer.
Once I make the call to program the device, my app sits there with nothing happening until it finishes. I wanted to add some kind of visual indicator that indeed things were working. I tried changing the cursor, but in a WorkItem, I don't have the context to do that (or do I?)
I also want to switch to a view that would show a progress bar. This is where I got REALLY confused:

Should I do this:
WorkItem catches event to program device
WorkItem switches the main view to the "Progress view"
The progress view presenter subscribes to events published by my Hardware driver class
WorkItem start the hardware driver process in a new thread
Hardware driver object raises events as it progresses which in turn update the "Progress view"
Hardware driver object raises "WorkDone" event which is handled in the parent WorkItem to switch the view from "ProgressView" to the appropriate post-process view.


Yikes. Is that correct? Should I use a service for my "Hardware Driver" process?

Since it takes so much up front work to implement a feature using CAB (that is not a critique, just an observation) I want to roll it out correct the first time.

If someone can see a clear picture of how I should do this and wants to share, you would really be helping me out (again).

Thanks for reading this far,
Steve K.
Mar 1, 2006 at 12:19 PM
originally posted by: sklett

Again looking at the apprasier app, it appears that the Appraisal Service Agent is runing in it's own thread as there is a progress bar in a view that is animated. Looking at the code, I don't see where a new thread is started. Is it a funcion of the Comman that creates a new thread behind the scenes?
Mar 1, 2006 at 3:18 PM
originally posted by: sklett

Alright, here is what I have done. If there is a better way, I would appreciate suggestions or tips.

<removed long description of app flow, reached message limit>

Here is the code, it will most likely make more sense than the above gibberish.

<View_A code>
private void listViewAvailableProgramsDoubleClick(object sender, EventArgs e)
{
ListViewItem selectedItem = ((ListView)sender).SelectedItems0;
if (selectedItem.Tag == null)
{
throw new NullReferenceException("The ListViewItem.Tag property is null");
}

FileInfo fileInfo = (FileInfo)selectedItem.Tag;
m_presenter.ProgramDevice(fileInfo);
}
</View_A code>


<ViewAPresenter code>
EventPublication(EventTopicNames.PROGRAM_DEVICE)
public event EventHandler ProgramDeviceHandler;


public void ProgramDevice(FileInfo programFile)
{
parentWorkItem.StateStateConstants.SELECTED_PROGRAM_FILE = programFile;

if(ProgramDeviceHandler != null)
{
ProgramDeviceHandler(this, new EventArgs());
}
}
</ViewAPresenter code>


Now onto the WorkItem code
<WorkItem code>
EventSubscription(EventTopicNames.PROGRAM_DEVICE)
public void ProgramDevice(object sender, EventArgs e)
{
FileInfo selectedFile = (FileInfo)StateStateConstants.SELECTED_PROGRAM_FILE;
if (selectedFile == null)
{
throw new NullReferenceException("Selected FileInfo from State is null");
}

ProgProgressView progressView = WorkItem.Items.AddNew<ProgProgressView>("ProgProgressView");
WorkItem.WorkspacesWorkspaceNames.MAIN_WORKSPACE.Show(progressView);


worker = new BackgroundWorker();
worker.DoWork += OnBackgroundWorker_DoWork;
worker.RunWorkerCompleted += ObBackgroundWorker_WorkComplete;

worker.RunWorkerAsync(selectedFile.FullName);
}

EventPublication(EventTopicNames.PROGRAMMER_PROGRESS_MESSAGE)
public event EventHandler<EventArgs<string>> ProgressUpdateMessage;

EventPublication(EventTopicNames.PROGRAMMER_FINISHED)
public event EventHandler ProgressFinished;

private void OnProgrammerStatusUpdate(bool success, string message)
{
if (ProgressUpdateMessage != null)
{
ProgressUpdateMessage(this, new EventArgs<string>(message));
}
}

private void OnBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
string filename = (string)e.Argument;
PMDMSP430Programmer.Program(filename, new ProgrammerProgressCallback(OnProgrammerStatusUpdate));
}

private void ObBackgroundWorker_WorkComplete(object sender, RunWorkerCompletedEventArgs e)
{
if (ProgressFinished != null)
{
ProgressFinished(this, EventArgs.Empty);
}
}
</WorkItem code>


<ProgressViewPresenter code>
EventSubscription(EventTopicNames.PROGRAMMER_PROGRESS_MESSAGE, ThreadOption.UserInterface)
public void ProgrammerProgressMessage(object sender, EventArgs<string> e)
{
m_view.ProgressMessageWriteLine(e.Data);
}

EventSubscription(EventTopicNames.PROGRAMMER_FINISHED, ThreadOption.UserInterface)
public void ProgrammerFinished(object sender, EventArgs e)
{
m_view.SetProgressControlsFinished();
}
</ProgressViewPresenter code>


Hopefully that will paint an accurate picture of what I'm trying to do and how I'm doing.

Thanks for reading (again),
Steve