Обновить данные из хранимой процедуры

У меня есть приложение фреймворка сущности С#. Я пытаюсь запустить хранимую процедуру из кода (без проблем). его длительный ход, около 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-задание из кода, а затем отслеживать журнал после этого с помощью вызовов в базе данных. Может быть, услуга-брокер может быть выбор?

любые мысли о том, с какой дорогой я должен пойти с этим типом проблемы? заранее спасибо Скотт

Ответ 1

Учитывая природу этих данных, являющихся просто статусом для пользователя, кажется, что делать READ UNCOMMITTED. Вы можете попробовать эти два варианта, оба из которых выглядят довольно прямолинейно:

Прежде всего, нужно установить свойство Session/Connection:

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 с NOLOCK. Первое предложение, основанное на ответе Фрэнка.Гермена, второе на основе слова Александра.

И только для того, чтобы он упоминался как опция, вы можете посмотреть в функции SNAPSHOT ISOLATION, которая была представлена ​​в SQL Server 2005:

Ответ 2

Если вы используете EF 6.0 и .NET 4.5, вы должны попробовать использовать последнюю функцию и поддержку acync: Анимационный запрос Entity Framework 6, Поддержка асинхронных шаблонов на основе задач в EF Похоже, что эта функция предназначена именно для ваших и подобных проблем.

Вы можете объединить его с DispatcherTimer, предложенным @user2002076.

Чтобы прочитать, что вы прогрессируете каждые x секунд, вы можете разработать другую хранимую процедуру, и внутри вы можете намекать на SQL с READ UNCOMMITTED.

Очевидно, все это требует EF 6.0 и .NET 4.5, но реализация будет приятной и короткой.