刷新存储过程中的数据

时间:2014-10-28 18:13:46

标签: c# sql entity-framework sql-server-2008-r2

我有一个c#实体框架应用程序。 我试图从代码运行存储过程(没有问题)。它长时间运行,大约30分钟。在进程完成时,我将每个事务的日志写入SQL表。 我希望从应用程序启动该过程,但然后显示登录屏幕的最后10条记录可能每10秒重新查询一次。这将显示进展。

 private void Window_Loaded_1(object sender, RoutedEventArgs e)
    {
        Task.Run(() => _serviceProduct.RefreshAllAsync());

        _cvsLog = (CollectionViewSource)(FindResource("cvsLog"));
        var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Interval = TimeSpan.FromSeconds(10);
        dispatcherTimer.Start();
    }


 private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        _cvsLog.Source = _serviceProduct.GetRefreshLog();
    }

我已将代码更改为简化。线程在dispatcherTime_Tick进程上阻塞。看起来存储过程很好。

这是被叫服务。

 public ObservableCollection<RefreshLog> GetRefreshLog()
    {
        using (var db = new HiggidyPiesEntities())
        {
            var recs = (from x in db.RefreshLogs orderby x.LG_ID descending select x).Take(30);
            var obs = new ObservableCollection<RefreshLog>(recs);
            return obs;
        }
    }

我一直在后台工作线路和task.run,但程序一直阻塞线程。

我甚至想过从代码启动SQL作业,然后通过调用数据库监视日志。 也许服务经纪人可能会考虑选择?

对于我应该解决这类问题的道路有什么想法? 在此先感谢斯科特

2 个答案:

答案 0 :(得分:4)

鉴于这些数据的性质只是用户的状态,做READ UNCOMMITTED似乎很好。您可以尝试这两个选项,这两个选项看起来都很简单:

首先要尝试设置会话/连接属性:

public ObservableCollection<RefreshLog> GetRefreshLog()
{
   using (var db = new HiggidyPiesEntities())
   {
      db.context.ExecuteStoreCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
      var recs = (from x in db.RefreshLogs orderby x.LG_ID descending select x).Take(30);
      var obs = new ObservableCollection<RefreshLog>(recs);
      return obs;
   }
}

要尝试的第二件事是通过EF设置事务隔离级别:

public ObservableCollection<RefreshLog> GetRefreshLog()
{

   using (var scope = new TransactionScope(TransactionScopeOption.Required,
             new TransactionOptions() {
                 IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
             }))
   {
      ObservableCollection<RefreshLog> obs;

      using (var db = new HiggidyPiesEntities())
      {
         var recs =
              (from x in db.RefreshLogs orderby x.LG_ID descending select x).Take(30);
         obs = new ObservableCollection<RefreshLog>(recs);
      }

      scope.Complete();
      return obs;
   }

}

这个问题取自这个问题的各种答案:Entity Framework with NOLOCK。第一个建议基于Frank.Germain的回答,第二个基于Alexandre的回答。

为了让它作为选项提到,您可能需要查看SQL Server 2005中引入的SNAPSHOT ISOLATION功能:

答案 1 :(得分:1)

如果您使用的是EF 6.0和.NET 4.5,则应尝试使用最新功能和acync支持:Entity Framework 6 async queryTask-based Asynchronous Pattern support in EF 看起来该功能的设计完全符合您和类似的问题。

您可以将其与@ user2002076建议的DispatcherTimer结合使用。

要每隔x秒读取一次进度,您可以开发另一个存储过程,在里面可以使用READ UNCOMMITTED提示SQL。

显然所有这些都需要EF 6.0和.NET 4.5,但实现起来会很好而且很短。