【问题标题】:UI locking during database connection数据库连接期间的 UI 锁定
【发布时间】:2014-02-27 16:08:14
【问题描述】:

当我尝试连接到不存在的实例时,UI 会锁定在我的应用程序中 我尝试过使用新线程,但这似乎不起作用

//从主类调用

 Dispatcher.BeginInvoke(new Action(
 () => Timedtask(instance, database)));    

 //Method

  public void Timedtask(string instance, string database)
        { 
            Timer.Start();
            Timer.Tick += delegate
            {
                if (!TimedTask.timer_Tick(instance, database))
                {
                    Dispatcher.CurrentDispatcher.Invoke(Stopped);
                }
            };

        }   

    // Try an open connection

         using (var con1 = new SqlConnection
                {
                    ConnectionString = @"Data Source=" + instanceName1 + ";Integrated Security=SSPI;" +
                 "MultipleActiveResultSets=true;"
                })


                {

                //more code
                 con1.Open();               
                //more code
                }

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    Dispatcher.BeginInvoke 将回调放在 UI 线程而不是后台线程上。因此,您的所有操作都在 UI 线程上运行。因此锁定了你的 UI。

    使用Task 或BackgroundWorker 委托后台线程调用。请注意,不能从后台线程修改任何 GUI 组件,因此您需要使用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke 将其编组回 UI 线程。


    Task.Factory.StartNew(() => { Timedtask(instance, database) });
    

    或

    如果使用 .Net 3.5,可以使用 backgroundWorker:

    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (s, e) => { Timedtask(instance, database); };
    worker.RunWorkerAsync();
    

    【讨论】:

    • @sw2020 - 有什么理由取消选择答案?
    【解决方案2】:

    我喜欢使用BackgroundWorkers

    设置:

    private BackgroundWorker bw;
    bw.DoWork += bw_DoWork;
    bw.RunWorkerCompleted += bw_WorkCompleted;
    

    实现这些方法:

    protected void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //Do database stuff here
    }
    
    protected void bw_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //This is called when the background worker is done.  This is where you can update the UI
    }
    

    然后启动worker:

    bw.RunWorkerAsync();
    

    【讨论】:

      【解决方案3】:

      你可以使用任务

      Task.Factory.StartNew(() =>
                  {
                      using (var con1 = new SqlConnection
                      {
                          ConnectionString = @"Data Source=" + instanceName1 + ";Integrated Security=SSPI;" +
                       "MultipleActiveResultSets=true;"
                      })
                      {
      
                          //more code
                          con1.Open();
                          //more code
                      }
                  });
      

      【讨论】:

        【解决方案4】:

        TPL 优于 BackgroundWorker。尝试使用 TPL(Task Parrel Liaberary),因为 Task Parellel 类是对 BackgroundWorker 的改进。它自然支持嵌套(父/子任务),使用新的取消 API,任务延续等。

        请打开Stephen Cleary关于“Reporting Progress from Tasks”的以下链接:

        Reporting Progress from Tasks

        【讨论】:

          【解决方案5】:

          您可以使用BackgroundWorker 解决此类问题。 在这里,您可以在WPF 应用程序中找到有关BackgroundWorker 的使用和实现的详细有用信息:How to use WPF Background Worker

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-02-25
            • 2015-10-27
            • 1970-01-01
            相关资源
            最近更新 更多