Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于WPF中线程的一个非常基本的解释?_C#_.net_Wpf_Multithreading - Fatal编程技术网

C# 关于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

我是WPF的新手。我在网上查找了几个关于线程的示例和教程。他们有自己的描述方式。但对于像我这样天真的人,我想用我自己的方式去理解

我可以使用数据库更新功能开始我的第一个线程

以下是场景:

我有大量数据要插入数据库。现在,让我们假设以下代码(只要我点击“继续”按钮,这个过程就会启动:

编辑: 我已经做了以下工作:

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
        });
    });