我正在调用一个返回Task<的异步方法。 CurrentCartridgeStatus>来自背景工作者。事情是,直到CurrentCartridgeStatus改变其我想继续调用它的状态。但是我没有等待这个方法调用,因为使DoWork方法异步会给我一个例外。
但在我的情况下,我当前的电话(请参阅StartCurrentRun方法)后台工作人员最初报告1%,然后它似乎保持空闲状态,并且状态发生变化后报告其余99%。请帮助我如何使BackCrocRun方法与BackCurrentRun方法同步进行后台工作报告。
private void StartCurrentRun(bool obj)
{
this.worker = new BackgroundWorker();
this.worker.WorkerReportsProgress = true;
this.worker.WorkerSupportsCancellation = true;
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
this.worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
IsLiveProgress = true;
StartTimer();
this.worker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
CreateEventLogs.WriteToEventLog(string.Format("Run with Assay:{0} Volume{1} has been started", SelectedAssay, SelectedVolume));
if (worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
int current = 1;
CurrentCartridgeStatus status = CurrentCartridgeStatus.NotProcessed;
var instance = ConnectToInstrument.InstrumentConnectionInstance;
do
{
var result = instance.StartCurrentRun(SelectedAssay.display_name, int.Parse(SelectedVolume.Remove(SelectedVolume.Length - 2, 2)));
//var result = Test(current);
status = result.Result;
CurrentStatus = status.ToString();
CreateEventLogs.WriteToEventLog("Run status - " + CurrentStatus);
//Thread.Sleep(2000);
worker.ReportProgress(Math.Min(current, 100));
current++;
}
while (status != CurrentCartridgeStatus.Processed);
ConnectToInstrument.IsAlreadyExecuted = false;
if (current < 100)
{
worker.ReportProgress(current + (100 - current));
}
}
这是StartCurrentRun方法。它内部调用一些固件逻辑。为了使这更清楚,整个ConnectToInstrument类。
public class ConnectToInstrument
{
private EventProxy _updater;
private IInstrument _instrument;
private QpCallBack _cb;
//private IQEvent @event;
private QpWrapper _qp;
private InstrumentTypes _type;
private CurrentInstrumentStatus InstrumentCurrentStatus = CurrentInstrumentStatus.NotReady;
private static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
public static bool IsAlreadyExecuted = false;
public bool IsConnected { get; set; }
private static ConnectToInstrument _instrumentConnectionInstance;
public static ConnectToInstrument InstrumentConnectionInstance
{
get
{
if (_instrumentConnectionInstance == null)
{
_instrumentConnectionInstance = new ConnectToInstrument();
}
return _instrumentConnectionInstance;
}
}
private ConnectToInstrument()
{
try
{
_cb = new QpCallBack();
_qp = new QpWrapper();
//var config = new ConfigManager();
//var client = new Dna2Client();
_type = InstrumentTypes.Simulator;
var factory = new ApiFactory(_cb, _qp, _type);
_instrument = factory.GetInstrument();
InitializeQf();
_updater = new EventProxy();
_updater.Start(1);
StartUiProxy().Forget();
}
catch (Exception ex)
{
//Log to Error Log
}
}
private async Task<object> StartUiProxy()
{
while (true)
{
try
{
var @event = await _updater.GetEvent();
switch ((QpSignals)@event.QSignal)
{
case QpSignals.INSTRUMENT_STATUS:
{
var status = @event as UiEvent<InstrumentStatus>;
if (status.Value != InstrumentStatus.Ready)
{
InstrumentCurrentStatus = CurrentInstrumentStatus.NotConnected;
continue;
}
else
{
InstrumentCurrentStatus = CurrentInstrumentStatus.Ready;
return Task.FromResult<object>(InstrumentStatus.Ready);
}
}
case QpSignals.TRAY_STATUS:
{
var status = @event as UiEvent<TrayStatus>;
if (status.QSignal == 6 && status.Value == TrayStatus.Opened)
{
return Task.FromResult<object>(TraySignals.OPEN);
}
else if (status.QSignal == 6 && status.Value == TrayStatus.Opened)
{
return Task.FromResult<object>(TraySignals.CLOSE);
}
return null;
}
case QpSignals.PROCESS_CARTRIDGE:
{
var status = @event as UiEvent<CartridgeStatus>;
if (status.Value == CartridgeStatus.Processing)
{
return status;
}
else if (status.Value == CartridgeStatus.Processed)
{
return status;
}
return null;
}
}
}
catch (Exception ex)
{
//Log to Error Log
}
}
}
private void InitializeQf()
{
QF.Instance.Initialize((int)QpSignals.MAX_SIGNAL - 1);
}
public async Task<bool> Connect()
{
bool status = false;
string[] ports = new string[40];
if (_type == InstrumentTypes.Dgx)
{
ports = await ComPortInfo.GetAvailablePortNamesForDevice("USB Serial Port");
if (ports == null || ports.Length == 0)
{
Exception ex = new Exception("No Serial Devices found.");
//Log
return false;
}
}
try
{
string thermPort = _type == InstrumentTypes.Simulator ? string.Empty : ports[0]; //ports[0] should be changed to combobox selected value
status = _instrument.Connect(ports[0]);
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
return status;
}
public async Task<CurrentInstrumentStatus> GetCurrentInstrumentStatus()
{
return await Task.FromResult(InstrumentCurrentStatus);
//_cb.InstrumentStatusUpdates(InstrumentStatus.Ready);
//var value = await _updater.GetEvent();
//var status = value as UiEvent<InstrumentStatus>;
//if (status.QSignal == 5 && status.Value == InstrumentStatus.Ready)
//{
// return CurrentInstrumentStatus.Ready;
//}
//return CurrentInstrumentStatus.Error;
}
public async Task<CurrentCartridgeStatus> StartCurrentRun(string Assay, int volume)
{
object value;
UiEvent<CartridgeStatus> status;
do
{
//await Task.Delay(1000);
//_cb.ProcessCartridge(CartridgeStatus.Processing);
if (!IsAlreadyExecuted)
{
_instrument.ProcessCartridge();
}
IsAlreadyExecuted = true;
//value = await StartUiProxy();
value = await _updater.GetEvent();
status = value as UiEvent<CartridgeStatus>;
}
while (status == null);
try
{
//IQEvent value;
if (status.QSignal == 9 && status.Value == CartridgeStatus.Processing)
{
return CurrentCartridgeStatus.Processing;
}
if (status.QSignal == 9 && status.Value == CartridgeStatus.Processed)
{
return CurrentCartridgeStatus.Processed;
}
}
catch (Exception ex)
{
//Log it
}
return CurrentCartridgeStatus.Unidentified;
}
}
这是CurrentCartridgeStatus枚举
public enum CurrentCartridgeStatus
{
Unidentified = 0,
NotProcessed = 1,
Processing = 2,
Processed = 3
}