我有一个订阅了几个方法的类,然后我在后台worker中执行。 (不确定我是否应该在后台工作程序中执行)该类触发一些事件,我想在屏幕上显示有关这些事件的信息。
流程如下:
在我调用AcceptCash
方法之后,它等待用户做一些事情。当操作完成并且收到所有现金并且需要分配更改时,执行StartDispense
事件并且该操作有效。我忙碌的屏幕按预期出现。
如果调用IncompleteDispense
事件,我想要显示“忙”屏幕,告诉用户不完全分配,并等待几秒钟。问题是在不完整的分配事件之后几乎立即触发ProcessComplete
事件。
此事件应等待不完整的分配屏幕消失,然后继续。但是我的等待部分似乎锁定了不完整的分配线程,并且不会始终显示不完整的消息,仅显示为快速闪烁,或者根本不显示。
这是我的代码的简单示例
private void continuePaymentProcess()
{
paymentController.IncompleteDispense += PaymentModule_IncompleteDispense;
paymentController.TransactionFinalised += PaymentModule_ProcessComplete;
paymentController.StartDispense += PaymentController_StartDispense;
//Is this necessary??
var worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
paymentController.AcceptCash(items.Values.Sum(x => x.ItemAmount));
};
worker.RunWorkerAsync();
}
private void PaymentController_StartDispense(object sender, EventArgs e)
{
ShowBusy();
}
private void PaymentModule_IncompleteDispense(decimal amount, CashItem[] cashItems)
{
DispenseMessage = true;
var worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
if (amountToDispense > 0) //This will only happen if a cashin was cancelled
paymentController.PrintVoucher(amountToDispense, "123123");
};
worker.RunWorkerCompleted += (o, ea) =>
{
System.Threading.Thread.Sleep(5000); //I think this is where my problem is
BlankPage.MainInstance.HideBusy();
DispenseMessage = false;
};
ShowBusy("INCOMPLETE DISPENSE!!!", $"Only {amount:c} was dispensed. A voucher for the rest of the money will be issued", false);
worker.RunWorkerAsync();
}
private void PaymentModule_ProcessComplete(object sender, EventArgs e)
{
var worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
while (DispenseMessage)
System.Threading.Thread.Sleep(10);
ShowBusy();
foreach (var item in payItems)
{
try
{
... Process some items
}
catch
{
}
}
};
worker.RunWorkerCompleted += (o, ea) =>
{
HideBusy();
ShowWelcomePage();
};
worker.RunWorkerAsync();
}
这是ShowBusy和HideBusy方法
public void ShowBusy(string Message = "Busy processing your request", string subMessage = "Please wait...", bool showProgress = true)
{
this.Dispatcher.InvokeIfRequired(() =>
{
loadingPanel.ShowProgress = showProgress;
loadingPanel.Message = Message;
loadingPanel.SubMessage = subMessage;
PanelLoading = true;
Task.Delay(1000);
}, true, System.Windows.Threading.DispatcherPriority.Render);
}
public void HideBusy()
{
this.Dispatcher.InvokeIfRequired(() =>
{
PanelLoading = false;
}, true, System.Windows.Threading.DispatcherPriority.Render);
}
我尽可能高优先,但没有帮助。
这是InvokeIfRequired扩展
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action, bool useInvoke = false, DispatcherPriority priority = DispatcherPriority.ContextIdle)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
if (useInvoke)
dispatcher.Invoke(action, priority);
else
dispatcher.BeginInvoke(action, priority);
return;
}
action();
}