I feel like I'm overdoing the async await stuff. I'm just learning. Maybe this isn't the best instance to be using this stuff.
I have a system with sensors that detect the completion of some action. I decided to approach this solution using asynchronous programming since I still need to communicate with other controllers as well as track the progress in changing states. Here is a snippet of the mess I made.
Is this a good instance to use this or should I revert back to tasks and events?
private async void StartTest_Click(object sender, RoutedEventArgs e)
{
if (AdamCont == null)
{ return; }
Abort = new CancellationTokenSource();
int reached = await AdamCont.RunTestConfigReached(Abort.Token);
if (reached == 0)
{
LightControl(SignalLight.GreenLight);
Model.TestState = TestCycleState.NotInTest;
}
else if (reached > 0)
{
LightControl(SignalLight.RedLight);
Model.TestState = TestCycleState.NotInTest;
// OnFailed(this, new FailedPositionEventArgs(Model.TestState, String.Format("Step {0} in test configuration failed", reached)));
//Now failedPosition can be called directly.
FailedPosition( new FailedPositionEventArgs(Model.TestState, String.Format("Step {0} in test configuration failed", reached)));
}
else
{
LightControl(SignalLight.AmberLight);
Model.TestState = TestCycleState.NotInTest;
}
}
The call is waiting on this sequence of operations.
public async Task<int> RunTestConfigReached(CancellationToken abortToken)
{
//extend seal bar
this.SetDIOState(true, DOChannels_5045_1.SEAL_CLAMP_DOWN);
this.SetDIOState(false, DOChannels_5045_1.SEAL_CLAMP_UP);
this.SetDIOState(false, DOChannels_5045_1.SEAL_BAR_CYLINDER_IN);
this.SetDIOState(true, DOChannels_5045_1.SEAL_BAR_CYLINDER_OUT);
this.LightControl(SignalLight.AmberLight);
Model.TestState = TestCycleState.SealBarLoadPosition;
bool reached = await Task<bool>.Factory.StartNew(() => SealBarLoadPosReached(200, 100));
if(!reached)
{
return 1;
}
if(abortToken.IsCancellationRequested)
{
return -1;
}
// Retract seal bar
this.SetDIOState(true, DOChannels_5045_1.SEAL_BAR_CYLINDER_IN);
this.SetDIOState(false, DOChannels_5045_1.SEAL_BAR_CYLINDER_OUT);
Model.TestState = TestCycleState.SealBarRetractPosition;
reached = await Task<bool>.Factory.StartNew(() => SealBarRetractPosReached(200, 100));
if(!reached)
{
return 2;
}
if (abortToken.IsCancellationRequested)
{
return -1;
}
//... etc...
}
RunTestConfigReached()
is waiting on individual states of the sensors. An example is:
private bool SealBarLoadPosReached(int timeout, int integrationTime = 200)
{
bool configurationReached = false;
int counter = 0;
while (counter < timeout && !configurationReached)
{
configurationReached =!Model.ChannelStates_5045_1[(int)DIChannels_5045_1.SEAL_BAR_HOME]
&& !Model.ChannelStates_5045_1[(int)DIChannels_5045_1.SEAL_PICUP_POSITION] //means it is
&& Model.ChannelStates_5045_1[(int)DIChannels_5045_1.SEAL_TEST_POSITION] // means it is not
&& Model.ChannelStates_5045_1[(int)DIChannels_5045_1.RIGHT_CLAMP_DOWN]
&& !Model.ChannelStates_5045_1[(int)DIChannels_5045_1.RIGHT_CLAMP_UP]
&& Model.ChannelStates_5045_1[(int)DIChannels_5045_1.LEFT_CLAMP_DOWN]
&& !Model.ChannelStates_5045_1[(int)DIChannels_5045_1.LEFT_CLAMP_UP];
Thread.Sleep(integrationTime);
counter++;
}
return configurationReached;
}
RunTestRoutine
supposed to run while other stuff on the UI is happening? Or is this a one-button form that firesRunTestRoutine
? \$\endgroup\$