我正在与后台工作者一起更新我正在处理的WPF UI中的进度条。这个后台工作者正在从我订阅的多个事件中获取进度更新,因为进度条经历了几个加载阶段,并且这些事件的百分比来自多个地方。这里有一些示例/伪代码解释我的意思
我的后台工作者的DoWork
方法以及我目前用于获取更新进度的方法
// These are working fine
private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
orderProcessing.OnOrderProgress += OrderStatus;
orderProcessing.OnStandardOrderProgress += StandardOrderStatus;
orderProcessing.CreateOrders(orders);
}
private void OrderStatus(int currentCount, int totalItems, string Message)
{
if (totalItems > 0)
bw.ReportProgress(Convert.ToInt32(((double)currentCount / (double)totalItems) * 100),
Message);
}
private void StandardOrderStatus(int currentCount, int totalItems, string Message)
{
if (totalItems > 0)
bw.ReportProgress(Convert.ToInt32(((double)currentCount / (double)totalItems) * 100),
Message);
}
我的订单处理类的一些代码
public abstract class OrderProcessing
{
public delegate void OrderProgress(int CurrentItems, int TotalItems, string Message);
public event MasterSalesOrder.StandardOrderProgress OnStandardOrderProgress;
public event OrderProgress OnOrderProgress;
public abstract List<MasterSalesOrder> CreateOrders(List<Order> orders);
}
包含CreateOrders()
覆盖方法的类中的一些代码public abstract class OrderProcessingFile : OrderProcessing
{
public event OrderProgress OnOrderProgress;
public override List<MasterSalesOrder> CreateOrders(List<Order> orders)
{
//Does Some Stuff
foreach(var stuff in stuffs)
{
OnOrderProgress(currentCount, totalCount, "Message");
}
}
}
由于我显然没有很好地解释这一点,我需要通过我在DoWork方法中创建的OrderProcessing类从OrderProcessingFiles OnOrderProgress事件获取信息。当我的代码永远不会直接实例化时,我不确定如何订阅事件OrderProcessingFile
类的一个实例,永远不会直接引用它。
我已经尝试寻找答案,但正如我的标题将显示我很难在某种程度上措辞以获得有用的结果,我真的坚持这一点。如果需要更多细节,请告诉我,我试图将我的代码仅删除相关部分,但我觉得我很难解释这一点。
答案 0 :(得分:0)
我建议你创建一个线程安全的单例进度管理器。然后让每个后台工作人员与更新联系。进度管理器将使用DispatcherTimer(在GUI线程上运行)来适当地更新GUI。
原始示例:
public static class StatusReportManager
{
// Standard singleton code to create the manager and access it.
// Start/create the dispatch time as well.
private static DispatcherTimer Timer { get; set; }
private static object _syncObject = new object();
public static void ReportStatus(...)
{
lock (_syncObject)
{
// Process any states and set instance properties for reading
// by the timer operation.
}
}
private void ShowStatus() // Used by the dispatch timer
{
lock (_syncObject)
{
// Do any updates to the GUI in here from current state.
}
}
}
答案 1 :(得分:0)
我已经意识到我真正想做的是什么,因此找到了答案。使用this MSDN文章中的方法,我实现了以下代码:
这是我的用户界面
private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
orderProcessing.OnOrderProgress += OrderStatus;
orderProcessing.CreateOrders(FanGlobal.BrandItems, FanGlobal.BrandItemMasterCustomers);
}
private void OrderStatus(object obj, OrderProcessing.OrderProgressEventArgs e)
{
if (e.totalCount > 0)
bw.ReportProgress(Convert.ToInt32(((double)e.currentCount / (double)e.totalCount) * 100),e.message);
}
这在我的OrderProcessing
班级
public event EventHandler<OrderProgressEventArgs> OnOrderProgress;
public class OrderProgressEventArgs : EventArgs
{
public int currentCount;
public int totalCount;
public string message;
public OrderProgressEventArgs(int c, int t, string m)
{
currentCount = c;
totalCount = t;
message = m;
}
}
protected virtual void OnOrderProgressChanged(OrderProgressEventArgs e)
{
EventHandler<OrderProgressEventArgs> handler = OnOrderProgress;
if (handler != null)
{
handler(this, e);
}
}
public abstract List<MasterSalesOrder> CreateOrders(List<BrandItem> BrandItems = null, List<BrandItemMasterCustomer> BrandItemMasterCustomers = null);
然后我就可以在我的孩子班OrderProcessingFile
中使用它了
public override List<MasterSalesOrder> CreateOrders(List<BrandItem> BrandItems = null, List<BrandItemMasterCustomer> BrandItemMasterCustomers = null)
{
//Do some Stuff
OnOrderProgressChanged(new OrderProgressEventArgs(count, totalItems, "Extracting"));
}
一切都像魅力一样。对于这个完全令人困惑的问题和我所拥有的明显的知识差距感到抱歉,但希望这将有助于其他人。