Reputation: 53
I have call back that I am getting from a firmware. When I get that call back I want to update my UI with the appropriate status. So I have property changed event that gets raised for each call back and I am subscribing to the event in background thread.
Please look at the like while(!WorkDone
) in DoWork
. I am blocking the call since I want the background thread to stay in DoWork till the update completes (Sould I use ManualResetEvent
?). Problem is even though I am setting the WorkDone
to true in PropertyChanged
it never gets set and the CurrentStatus with which I am updating the UI never updates and the program goes to an infinate loop. Please help.
private void StartCurrentRun(bool obj)
{
this.worker = new BackgroundWorker();
this.worker.WorkerReportsProgress = true;
this.worker.WorkerSupportsCancellation = true;
StartTimer();
PropertyCallBackChangedInstance.PropertyChanged -= PropertyCallBackChangedInstance_PropertyChanged;
WhenCancelledBlurVolumesGrid = false;
OriginalTime = SelectedVolumeEstimatedTime();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
this.worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
IsLiveProgress = true;
this.worker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
try
{
CreateEventLogs.WriteToEventLog(string.Format("Run with Assay:{0} Volume{1} has been started", SelectedAssay, SelectedVolume), LogInformationType.Info);
var instance = ConnectToInstrument.InstrumentConnectionInstance;
instance.InitalizeRun(PopulateRespectiveVolumes());
PropertyCallBackChangedInstance.PropertyChanged += PropertyCallBackChangedInstance_PropertyChanged;
while (!WorkDone)
{
continue;
}
}
catch (Exception ex)
{
CreateEventLogs.WriteToEventLog(string.Format("{0} - {1}", "Error occured during Run", ex.Message), LogInformationType.Error);
}
}
private void PropertyCallBackChangedInstance_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//bool stepDone = false;
if (e.PropertyName == "RunStepStatusName")
{
var value = sender as InstrumentCallBackProperties;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => {
CurrentStatus = value.RunStepStatusName;
if (value.RunStepStatusName == "Step5")
{
WorkDone = true;
}
}));
//stepDone = true;
}
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.ProgressValue = e.ProgressPercentage;
}
Here is the InitailizeRun method when I call this I get call backs
public async void InitalizeRun(VolumeInfo volumeInfo)
{
AssayInfo AssayInfo = new AssayInfo();
AssayInfo.IVolume = volumeInfo;
CartridgeStepStatus StepStatus = new CartridgeStepStatus();
StepStatus.Data = AssayInfo;
await Task.Run(() => _instrument.ProcessCartridge(StepStatus));
}
And here is the call back whenever I get it I am updating the property
public void ProcessCartidge<T>(T data)
{
InstrumentCallBackPropertiesInstance.RunStepStatusName = data.ToString();
}
Upvotes: 1
Views: 260
Reputation: 3513
You can replace the BackgroundWorker
with a Task.Run
since it doesnt work well with async
and await
.
Task.Run
starts a backgroundthread and should contain the code that needs to run on a seperate thread. If you want to report progress, you should use a IProgress parameter.
This example should get you in the right direction. You can build your final solution based on this.
protected override async void OnLoadAsync( EventArgs e )
{
base.OnLoad( e );
try
{
IsLiveProgress = true;
await StartCurrentRunAsync( true );
}
catch ( Exception ex )
{
CreateEventLogs.WriteToEventLog( string.Format( "{0} - {1}" , "Error occured during Run" , ex.Message ) , LogInformationType.Error );
}
finally
{
IsLiveProgress = false;
}
}
private Task StartCurrentRunAsync( bool obj )
{
StartTimer();
PropertyCallBackChangedInstance.PropertyChanged -= PropertyCallBackChangedInstance_PropertyChanged;
WhenCancelledBlurVolumesGrid = false;
OriginalTime = SelectedVolumeEstimatedTime();
return Task.Run( () =>
{
CreateEventLogs.WriteToEventLog( string.Format( "Run with Assay:{0} Volume{1} has been started" , SelectedAssay , SelectedVolume ) ,
LogInformationType.Info );
var instance = ConnectToInstrument.InstrumentConnectionInstance;
return instance.InitalizeRun( PopulateRespectiveVolumes() );
} );
}
private void PropertyCallBackChangedInstance_PropertyChanged( object sender , PropertyChangedEventArgs e )
{
//bool stepDone = false;
if ( e.PropertyName == "RunStepStatusName" )
{
var value = sender as InstrumentCallBackProperties;
Dispatcher.CurrentDispatcher.BeginInvoke( ( Action ) ( () =>
{
CurrentStatus = value.RunStepStatusName;
if ( value.RunStepStatusName == "Step5" )
{
WorkDone = true;
}
} ) );
//stepDone = true;
}
}
Upvotes: 1