2014-10-28 1 views
2

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 작업을 시작한 다음 데이터베이스 호출을 통해 로그를 모니터링한다고 생각했습니다. 아마도 서비스 브로커가 고려해야 할 선택 일 수 있습니까?

어떤 유형의 문제와 관련하여 어떤 유형의 문제에 대해 생각해보십시오. 사전에 감사 스콧

+0

DispatcherTimer를 사용해 볼 수 있습니다. 이것은 UI 스레드에서 실행된다는 점을 제외하고는 백그라운드 작업자처럼 작동합니다. 타이머가 10 초마다 ItemsSource를 새로 고칠 수 있습니다. –

+0

감사합니다. 도움이 될지도 모른다. – scottsanpedro

+0

당신의 UI 스택은 묻고 삭제 된 WPF 태그와 완전히 무관합니다. –

답변

4

이 데이터의 성격이 사용자에게 단순한 상태라는 점을 감안할 때, 읽지 않은 것은 괜찮습니다. 트랜잭션 격리를 설정하는 것입니다

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 's를 바탕으로 한 두 번째 제안.

+2

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED를 사용하는 첫 번째 섹션에서 프로세스가 완벽하게 시작되었습니다. – scottsanpedro

+0

@clive,보고 싶은 추가 정보가 있습니까? –

+1

아니, 잘 할거야. 대단히 고마워요 – Clive

1

당신은 당신이 최신 기능 및 acync 지원 사용하려고한다 EF 6.0 및 .NET 4.5을 사용하는 경우 : Entity Framework 6 async queryTask-based Asynchronous Pattern support in EF 기능이 디자인이 유사한 문제를 정확히 것 같습니다.

@ user2002076이 제안한 DispatcherTimer과 결합 할 수 있습니다.

매 x 초마다 다른 저장 프로 시저를 개발할 수 있고 읽지 않은 채로 SQL을 힌트로 표시 할 수 있습니다.

분명히 모든 것들은 EF 6.0과 .NET 4.5가 필요하지만, 구현은 멋지고 짧을 것입니다.