C# 长流程、绑定更新和UI冻结
我的WPF/C#程序使用在特定序列中调用的不同方法。 每个方法都绑定到UI,经过长时间的处理后显示一些数据。 我正在使用调度程序,因为调用的方法位于另一个线程中。 我还希望在不冻结UI的情况下执行此过程,例如,能够取消该过程并自由替换窗口 我的问题是,用户界面根本没有更新(进度条、计算步骤),取消按钮在计算结束之前不会运行。 事实上,即使挂起的长流程没有完成,也不知道如何立即取消常规序列 我不是100%确定使用正确的方法,有没有人有更好的解决方案或建议 前C# 长流程、绑定更新和UI冻结,c#,wpf,binding,dispatcher,C#,Wpf,Binding,Dispatcher,我的WPF/C#程序使用在特定序列中调用的不同方法。 每个方法都绑定到UI,经过长时间的处理后显示一些数据。 我正在使用调度程序,因为调用的方法位于另一个线程中。 我还希望在不冻结UI的情况下执行此过程,例如,能够取消该过程并自由替换窗口 我的问题是,用户界面根本没有更新(进度条、计算步骤),取消按钮在计算结束之前不会运行。 事实上,即使挂起的长流程没有完成,也不知道如何立即取消常规序列 我不是100%确定使用正确的方法,有没有人有更好的解决方案或建议 前 public void calcula
public void calculation命令()
{
var bkw=新的BackgroundWorker()
bkw.DoWork+=工作;
bkw.RunWorkerAsync(Dispatcher.CurrentDispatcher);
}
公共作废工作(对象发送者、DoWorkEventArgs e)
{
var dispatcher=e.作为调度程序的参数;
var dispatcherPriority=dispatcherPriority.Background;
行动;
动作=()=>
{
更新(状态信息待定);
};
dispatcher.BeginInvoke(操作,dispatcherPriority);
ViewModel1 ViewModel1=null;
动作=()=>
{
UpdateProgress(10,“抽样计算”);
viewModel1=Application.GetEchantillonnage();//长进程
};
dispatcher.BeginInvoke(操作,dispatcherPriority);
列表长度列表=null;
动作=()=>
{
UpdateProgress(20,“长度计算”);
lengthList=AlgorithmLibrary.LengthCalculations(viewModel1);//长进程
};
dispatcher.BeginInvoke(操作,dispatcherPriority);
ViewModel2 ViewModel2=null;
动作=()=>
{
UpdateProgress(30,“发动机计算”);
viewModel2=Application.GetEngine();//长进程
AlgorithmLibrary.EngineCalculations(viewModel2);//长过程
var FilteredLength=AlgorithmLibrary.LengthFilter(lengthList);//长进程
};dispatcher.BeginInvoke(操作,dispatcherPriority);
///…执行的其他操作将进度值增加到100%
动作=()=>
{
UpdateStatut(StatutsInformation.Finished);
};
dispatcher.BeginInvoke(操作,dispatcherPriority);
}
私人无效信息更新(状态信息状态信息)
{
ViewModelLoading.StationFormation=StationFormation;
}
私有void UpdateProgress(int值,字符串标签)
{
ViewModelLoading.Progress=值;
ViewModelLoading.Step=标签;
}
感谢在方法
工作中
您正在后台线程上执行。每次调用dispatcher.BeginInvoke
时,传递给此方法的操作将在UI线程上执行。看到你现在在做什么了吗?请再次查看此代码
// Here, we are on a background thread
action = () =>
{
// This action is NOT executing yet! We are just defining it.
UpdateProgress(10, "Sampling calculations");
// This is going to execute on the thread that executes this action!
viewModel1 = Application.GetEchantillonnage();//Long process
};
// here, we are still on the background thread, but we are telling the
// dispatcher to marshall the action onto the UI thread to execute it!
dispatcher.BeginInvoke(action, dispatcherPriority);
您正在UI线程上执行长期运行的工作:/
不过,解决办法很简单。简单地把你的作品拉出来,并把它放在背景线程中。这是相同的代码,但工作正常(除非代码中出现其他问题)
在方法
Work
中,您正在后台线程上执行。每次调用dispatcher.BeginInvoke
时,传递给此方法的操作将在UI线程上执行。看到你现在在做什么了吗?请再次查看此代码
// Here, we are on a background thread
action = () =>
{
// This action is NOT executing yet! We are just defining it.
UpdateProgress(10, "Sampling calculations");
// This is going to execute on the thread that executes this action!
viewModel1 = Application.GetEchantillonnage();//Long process
};
// here, we are still on the background thread, but we are telling the
// dispatcher to marshall the action onto the UI thread to execute it!
dispatcher.BeginInvoke(action, dispatcherPriority);
您正在UI线程上执行长期运行的工作:/
不过,解决办法很简单。简单地把你的作品拉出来,并把它放在背景线程中。这是相同的代码,但工作正常(除非代码中出现其他问题)
您的代码不断进入后台线程,以便在UI线程上执行长时间运行的任务。Dispatcher.BeginInvoke将代理封送回UI线程 试试这个:
private void RunOnUI(Action uiAction, DispatcherPriority dispatcherPriority = DispatcherPriority.Background)
{
dispatcher.BeginInvoke(uiAction, dispatcherPriority);
}
public void Work(object sender, DoWorkEventArgs e)
{
var dispatcher = e.Argument as Dispatcher;
var dispatcherPriority = DispatcherPriority.Background;
Action action;
runOnUI(() =>
{
UpdateStatut(StatutsInformation.Pending);
});
ViewModel1 viewModel1 = null;
RunOnUI(() =>
{
UpdateProgress(10, "Sampling calculations");
});
viewModel1 = Application.GetEchantillonnage();//Long process
List<double> lengthList = null;
RunOnUI(() =>
{
UpdateProgress(20, "Length calculations");
});
lengthList = AlgorithmLibrary.LengthCalculations(viewModel1);//Long process
ViewModel2 viewModel2 = null;
RunOnUI(() =>
{
UpdateProgress(30, "Engine calculations");
};
viewModel2 = Application.GetEngine();//Long process
AlgorithmLibrary.EngineCalculations(viewModel2);//Long process
var FilteredLength = AlgorithmLibrary.LengthFilter(lengthList);//Long process
///... Others actions executed incrementing the progress value to 100%
RunOnUI(() =>
{
UpdateStatut(StatutsInformation.Finished);
});
}
private void rununui(Action uiAction,DispatcherPriority DispatcherPriority=DispatcherPriority.Background)
{
dispatcher.BeginInvoke(uiAction,dispatcherPriority);
}
公共作废工作(对象发送者、DoWorkEventArgs e)
{
var dispatcher=e.作为调度程序的参数;
var dispatcherPriority=dispatcherPriority.Background;
行动;
runOnUI(()=>
{
更新(状态信息待定);
});
ViewModel1 ViewModel1=null;
RunOnUI(()=>
{
UpdateProgress(10,“抽样计算”);
});
viewModel1=Application.GetEchantillonnage();//长进程
列表长度列表=null;
RunOnUI(()=>
{
UpdateProgress(20,“长度计算”);
});
lengthList=AlgorithmLibrary.LengthCalculations(viewModel1);//长进程
ViewModel2 ViewModel2=null;
RunOnUI(()=>
{
UpdateProgress(30,“发动机计算”);
};
viewModel2=Application.GetEngine();//长进程
AlgorithmLibrary.EngineCalculations(viewModel2);//长过程
var FilteredLength=AlgorithmLibrary.LengthFilter(lengthList);//长进程
///…执行的其他操作将进度值增加到100%
RunOnUI(()=>
{
UpdateStatut(StatutsInformation.Finished);
});
}
您的代码不断闯入后台线程,在UI线程上执行长时间运行的任务。Dispatcher.BeginInvoke将代理封送回UI线程
试试这个:
private void RunOnUI(Action uiAction, DispatcherPriority dispatcherPriority = DispatcherPriority.Background)
{
dispatcher.BeginInvoke(uiAction, dispatcherPriority);
}
public void Work(object sender, DoWorkEventArgs e)
{
var dispatcher = e.Argument as Dispatcher;
var dispatcherPriority = DispatcherPriority.Background;
Action action;
runOnUI(() =>
{
UpdateStatut(StatutsInformation.Pending);
});
ViewModel1 viewModel1 = null;
RunOnUI(() =>
{
UpdateProgress(10, "Sampling calculations");
});
viewModel1 = Application.GetEchantillonnage();//Long process
List<double> lengthList = null;
RunOnUI(() =>
{
UpdateProgress(20, "Length calculations");
});
lengthList = AlgorithmLibrary.LengthCalculations(viewModel1);//Long process
ViewModel2 viewModel2 = null;
RunOnUI(() =>
{
UpdateProgress(30, "Engine calculations");
};
viewModel2 = Application.GetEngine();//Long process
AlgorithmLibrary.EngineCalculations(viewModel2);//Long process
var FilteredLength = AlgorithmLibrary.LengthFilter(lengthList);//Long process
///... Others actions executed incrementing the progress value to 100%
RunOnUI(() =>
{
UpdateStatut(StatutsInformation.Finished);
});
}
private void rununui(Action uiAction,DispatcherPriority DispatcherPriority=DispatcherPriority.Background)
{
dispatcher.BeginInvoke(uiAction,dispatcherPriority);
}
公共作废工作(对象发送者、DoWorkEventArgs e)
{
var dispatcher=e.作为调度程序的参数;
var dispatcherPriority=dispatcherPriority