所以我有一个可以通过我的GUI执行的任务,该任务将提取信息以使用SQL数据库查询响应填充ViewModel。 假设我想开始这项任务并让我的gui自由地继续其他事情,同时播放“搜索”动画,在WPF中执行此操作的正确方法是什么MVVM?我假设您需要启动一个异步进程并设置一个绑定到启动动画故事板的数据触发器的bool。 但是我该怎么用来启动这个过程?线程?我还是WPF的新手,只是想确保我使用的是正确的类。
答案 0 :(得分:8)
我使用BackgroundProcess线程来做这样的事情。
以下是MSDN的链接:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
与此相关的其他详细信息。
您有三个与BackgroundProcess对象关联的事件:DoWork,ReportProgress和WorkCompleted。
现在,要使用它 - 并将它与observablecollection一起使用 - 你想要告诉BackgroundProcess对象能够REPORT PROGRESS(这是一个我总是明确设置的布尔属性,以及允许取消)。
现在开始一个进程,你将调用RunWorkerAsync方法。如果需要传递数据,此方法可以接受OBJECT变量(如果需要多于1个值,则创建要传递给RunWorkerAsync的结构)。
RunWorkerAsync会触发DoWork事件,因此控制权将转移到您的DoWork事件处理程序。这是我正在使用它的(已消毒的)代码:
Dim dt As System.Data.DataTable
dt = da.GetDataTable(sql, System.Data.CommandType.Text, params)
For Each row As System.Data.DataRow In dt.Rows
If loadQuestionsWorker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
Dim item As New DataObject
// Assign Item Values
backgroundProcessObject.ReportProgress(1, item)
Next
这里发生的事情是,我从我的数据层获取数据表,然后当这个后台进程没有被取消时,我正在走数据表,当我构建一个新的DataObject时,我报告该对象正在建设中。
现在,在我的ProgressChanged事件处理程序中(ReportProgress方法引发了ProgressChanged事件)控件又返回到UI线程中,因此我可以做一些事情,比如影响UI并将我正在报告的元素添加到ObservableCollection。 / p>
最后,在我的WorkedCompleted事件处理程序(当DoWork事件处理程序方法运行完成时引发其相应的事件)时,我检查我的进度是否被取消(这有时意味着我要转储ObservableCollection)我可能或者可能不会影响用户界面(例如删除“搜索”动画。
答案 1 :(得分:2)
您可以明确地开始新的Thread
或BackgroundWorker
,也可以使用ThreadPool
。我不知道在MVVM中这样做的任何推荐方法......
如果您的异步操作正在填充绑定到控件的ObservableCollection,请注意您不能在其他线程上向其添加项目。您需要在控件的调度程序线程上执行此操作。或者您也可以使用this collection,它会在适当的线程上引发CollectionChanged事件
答案 2 :(得分:1)
var t = new Thread((ThreadStart)delegate
{
DoWork(...)
Dispatcher.BeginInvoke((Action)delegate
{
SomethingOntheUiThread(...)
FinishedWork(...);
}
});
t.Start();