C# 关于WPF中线程的一个非常基本的解释?
我是WPF的新手。我在网上查找了几个关于线程的示例和教程。他们有自己的描述方式。但对于像我这样天真的人,我想用我自己的方式去理解 我可以使用数据库更新功能开始我的第一个线程 以下是场景: 我有大量数据要插入数据库。现在,让我们假设以下代码(只要我点击“继续”按钮,这个过程就会启动: 编辑: 我已经做了以下工作:C# 关于WPF中线程的一个非常基本的解释?,c#,.net,wpf,multithreading,C#,.net,Wpf,Multithreading,我是WPF的新手。我在网上查找了几个关于线程的示例和教程。他们有自己的描述方式。但对于像我这样天真的人,我想用我自己的方式去理解 我可以使用数据库更新功能开始我的第一个线程 以下是场景: 我有大量数据要插入数据库。现在,让我们假设以下代码(只要我点击“继续”按钮,这个过程就会启动: 编辑: 我已经做了以下工作: var task = new Task(() => { for (int i=0; i<10; i++) { //Create ne
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";
var task=新任务(()=>
{
对于(int i=0;i
{
label.Content=printerStatus();//将返回“纸张用完”、“打印”、“卡纸”等。
},
TaskScheduler.FromCurrentSynchronizationContext());
label.Content=“发送到打印机”;
程序将返回错误,说明“调用线程必须是STA,因为许多UI组件都需要STA。”
我不知道下一步该做什么。请帮助!您需要使用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
}
//创建后台工作程序
BackgroundWorker工人=新的BackgroundWorker();
//分配工作
worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
//开始工作
worker.RunWorkerAsync();
//这项工作将在后台完成
无效工作线程(对象发送器,工作线程目标)
{
设置初始值=0;
设置maxData=1000
直到首字母
多线程处理与您选择的UI技术(Wpf或Winforms)没有任何关系-当您必须切换到UI线程来更新控件时,只有细微的区别
根据您的代码示例,我必须说,从sql server到您的程序没有回调的可能性。如果您想拥有该功能,必须在C#而不是sql语句中实现循环
编辑:
根据OP I的评论,在前台添加一个后台工作和更新UI的示例:
下面是处理WPF线程的示例代码段
考虑这种情况。
我们必须从服务器上获取一些数据,然后我们就可以处理数据了。
意味着我们的下一个操作完全依赖于回调或任务的完成
在这种情况下,我们可以使用任务工厂continue,方法如下
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
});
});
ObservableCollection图像=新的ObservableCollection();
TaskFactory tFactory=新的TaskFactory();
tFactory.StartNew(()=>
{
对于(int i=0;i<50;i++)
{
//从服务器获取映像路径
System.Windows.Application.Current.Dispatcher.BeginInvoke((操作)委托)()
{
//在UI中更新进度条
});
图片。添加((“”);
}
}).ContinueWith(t=>
{
如果(t.IsFaulted)
{
//如果线程有故障,则出现异常
抛出t异常;
}
System.Windows.Application.Current.Dispatcher.BeginInvoke((操作)委托)()
{
//处理图像和显示
});
});
how?请用代码告诉我!我需要调用所有名称空间和类!这将如何编译?你是什么意思?代码Set initial…
只是代表一些真实的code@HarisHasan:如果我想在后台线程中添加一些UI,那该怎么办?为此,请发布一个单独的问题,这只是一个示例Think.Can您可以为我展示不同场景的另一种方法吗?例如,使用标签“searching…”搜索超大列表,并在找到时将其关闭。任何示例都可以让我知道最基本的方法。@user995387:根据您的评论,我在回答中添加了一个示例。我不能创建新的UI(网格)吗在任务中?请阅读我更新的查询!@user995387:对于未来,请记住:对于新问题,请提出新问题!您会遇到此错误,因为您希望在后台任务中创建网格,这是不可能的。您必须在UI线程中执行此操作。但是如果您将任务切换到UI线程,您将不会有任何“多线程”-优点,因为此时线程正在“前台”运行.hmm…我启动了新线程:我不能创建一个不同的UI线程来创建UI或flowdocument并在后台线程中使用它吗?@TomTom:你在编程方面考虑得太多了。总结是,我想在后台做一些繁重的任务,并在主窗口中显示它的进度。无论如何,谢谢你的建议。我实际上不想t显示查询更新消息,甚至不显示单个查询。Google并了解:System.Threading.SynchronizationContext.Current。
//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
}
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();
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
});
});