我对WPF非常新。我在互联网上查看了几个关于线程的示例和教程。他们有自己的描述方式。但是对于像我这样的天真,我想用自己的风格来理解。
我可以使用数据库更新功能开始我的第一次线程化。
以下是该方案:
我要在数据库中插入大量数据。现在让我们假设以下代码(一旦我点击“继续”按钮,这个过程就会启动:
int initial = 0;
int maxData = 10
while (initial<maxData) {
//Database query here
}
上述过程将在不同的主题中运行。
接下来我在主窗口中有一个“标签”。对于每个数据库查询,我想在标签中显示一些消息。
例如,
// this will happen in default UI thread.
label.Content = "Updating"; // Specifically for @TomTom ;)
编辑: 我做了以下事情:
var task = new Task(() =>
{
for (int i=0; i<10; i++) {
//Create new Grid HERE
// Add Table with some dynamic data here..
// print the above Grid here.
}
});
task.ContinueWith((previousTask) =>
{
label.Content = printerStatus(); // will return "Out of Paper", "printing", "Paper jam", etc.
},
TaskScheduler.FromCurrentSynchronizationContext());
label.Content = "Sending to printer";
程序将返回错误,说“调用线程必须是STA,因为许多UI组件都需要这个。”
我不知道下一步该做什么。请帮忙!
答案 0 :(得分:9)
您需要将BackgroundWorker用于长时间运行的任务,并使用Dispatcher更新之间的UI
//create background worker
BackgroundWorker worker = new BackgroundWorker();
//assign it work
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
//start work
worker.RunWorkerAsync();
//this work will be done in background
void worker_DoWork(object sender, DoWorkEventArgs e)
{
SET initial = 0;
SET maxData = 1000
DO UNTIL initial <1000
CREATE db query "INSERT INTO (col1,col2,col3) VALUES(value1,value2,value3);"
//in between your work do this to update label
label.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,new Action(delegate()
{
Label.Content = "SomeValue";
}
));
END DO
}
答案 1 :(得分:3)
多线程无法处理您选择的UI技术(Wpf或Winforms) - 当您必须切换到UI线程来更新控件时,只会略有不同。
< / LI>根据你的代码示例,我必须说,从sql server到你的程序没有回调的可能性。如果你想拥有该功能,你必须在C#中实现循环而不是在sql语句中。
修改强>
根据OP的评论,我添加了一个后台工作示例,并使用TPL (Task Parallel Library)更新前景中的UI:
var task = new Task(() =>
{
// Do something very long ...
});
task.ContinueWith((previousTask) =>
{
label.Content = "Background work has finished.";
},
TaskScheduler.FromCurrentSynchronizationContext());
label.Content = "Background work is running.";
task.Start();
答案 2 :(得分:0)
以下是处理WPF线程的示例代码段。
请考虑这种情况。
我们必须从服务器获取一些数据,然后我们才能使用数据。 意味着我们的下一步行动完全取决于任务的回调或完成。
在这种情况下,我们可以使用任务工厂ContinueWith方法,如下面的
ObservableCollection images = new ObservableCollection();
TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
for (int i = 0; i < 50; i++)
{
//GET IMAGE Path FROM SERVER
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// UPDATE PROGRESS BAR IN UI
});
images.Add(("");
}
}).ContinueWith(t =>
{
if (t.IsFaulted)
{
// EXCEPTION IF THREAD IS FAULT
throw t.Exception;
}
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
//PROCESS IMAGES AND DISPLAY
});
});