Udostępnij za pośrednictwem


Dodawanie obsługę debugowania w niestandardowego zadania

Integration Services Run -czas silnika umożliwia pakietów, zadania i inne typy pojemników zawieszony podczas wykonywania, za pomocą punktów przerwania.Użyj punktów przerwania pozwala przeglądu i poprawiać błędy, które uniemożliwiają poprawne działanie aplikacji lub zadań.Architektura punkt przerwania umożliwia klientowi oceny Uruchom -czas wartość obiektów w pakiecie w określonych punktach wykonanie podczas przetwarzania zadania jest zawieszone.

Niestandardowe zadania deweloperzy mogą używać tej architektury do tworzenia niestandardowych punkt przerwania celów za pomocą IDTSBreakpointSite i jego nadrzędnej interfejs, IDTSSuspend.IDTSBreakpointSite Interfejs definiuje interakcji między Uruchom -czas silnika i zadania do tworzenia i zarządzania punkt przerwania niestandardowych witryn lub celeIDTSSuspend Interfejs udostępnia metody i właściwości, które są wywoływane przez uruchomienie -czas silnika powiadomić zadania, aby wstrzymać lub wznowić wykonywanie.

Witryny punkt przerwania lub miejsce docelowe jest punktem wykonanie zadania, gdzie zawieszone przetwarzania.Wybierz użytkowników z witryny punkt przerwania dostępne w Ustawić punkty punkt przerwania okno dialogowe.Na przykład oprócz opcji domyślnych punkt przerwania kontenera pętli Foreach oferuje "Przerwę na początku każdej iteracji pętli" Opcja.

Gdy zadanie osiągnie docelową przerwania podczas wykonywania, ocenia miejsce docelowe punkt przerwania do ustalenia, czy punkt przerwania jest włączone.Oznacza to, że użytkownik chce wykonanie się przy tym punkt przerwania.Jeśli punkt przerwania jest włączony, zadania podnosi OnBreakpointHit zdarzenia w celu uruchomienia -czas silnika.Uruchom -czas silnika reaguje zdarzenie wywołania Suspend metoda każdego zadania działa obecnie w pakiecie.Wykonanie zadania zostanie wznowione, gdy środowisko wykonawcze wywołuje ResumeExecution metoda zawieszone zadań.

Zadania, które nie korzystają z punktami przerwania nadal należy implementować IDTSBreakpointSite i IDTSSuspend interfejsów.Gwarantuje to, że zadanie jest zawieszone poprawnie po innych obiektów w pakiet podnieść OnBreakpointHit zdarzenia.

Interfejs IDTSBreakpointSite i BreakpointManager

Zadania tworzenia celów punkt przerwania przez wywołanie CreateBreakpointTarget metoda BreakpointManager, zapewniając całkowitą Identyfikatora i ciąg opisu jako parametry.Gdy zadanie osiągnie punkt w jego kod, który zawiera element miejsce docelowe punkt przerwania, ocenia przerwania docelowego przy użyciu IsBreakpointTargetEnabled metoda, aby określić, czy ten punkt przerwania jest włączony.Jeśli true, powiadamia zadania Uruchom -czas silnika poprzez podnoszenie OnBreakpointHit zdarzeń.

IDTSBreakpointSite Interfejs definiuje pojedynczą metoda AcceptBreakpointManager, która jest wywoływana przez uruchomienie -czas silnika podczas tworzenia zadania.Ta metoda zapewnia jako parametr BreakpointManager obiekt, który jest następnie używany przez zadanie tworzenia i zarządzania nimi punkty przerwania.Zadania powinny być przechowywane BreakpointManager lokalnie do użytku podczas Validate i Execute metody.

Następujący przykładowy kod ilustruje sposób utworzyć miejsce docelowe punkt przerwania za pomocą BreakpointManager.Wywołania próbki OnBreakpointHit metoda podnieść zdarzenie.

public void AcceptBreakpointManager( BreakpointManager breakPointManager )
{
   //   Store the breakpoint manager locally.
   this.bpm  = breakPointManager;
}
public override DTSExecResult Execute( Connections connections,
  Variables variables, IDTSComponentEvents events,
  IDTSLogging log, DtsTransaction txn)
{
   //   Create a breakpoint.
   this.bpm.CreateBreakPointTarget( 1 , "A sample breakpoint target." );
...
   if( this.bpm.IsBreakpointTargetEnabled( 1 ) == true )
      events.OnBreakpointHit( this.bpm.GetBreakpointTarget( 1 ) );
}
Public Sub AcceptBreakpointManager(ByVal breakPointManager As BreakpointManager)

   ' Store the breakpoint manager locally.
   Me.bpm  = breakPointManager

End Sub

Public Overrides Function Execute(ByVal connections As Connections, _
  ByVal variables As Variables, ByVal events As IDTSComponentEvents, _
  ByVal log As IDTSLogging, ByVal txn As DtsTransaction) As DTSExecResult

   ' Create a breakpoint.
   Me.bpm.CreateBreakPointTarget(1 , "A sample breakpoint target.")

   If Me.bpm.IsBreakpointTargetEnabled(1) = True Then
      events.OnBreakpointHit(Me.bpm.GetBreakpointTarget(1))
   End If

End Function

Interfejs IDTSSuspend

IDTSSuspend Interfejs definiuje metody, które są wywoływane przez uruchomienie -czas silnika, wstrzymuje lub wznawia wykonanie zadań.IDTSSuspend Interfejs jest implementowany przez IDTSBreakpointSite interfejsu i jego Suspend i ResumeExecution metody zazwyczaj są zastępowane przez niestandardowe zadania.Kiedy odbiera silnika run-czas OnBreakpointHit wywołuje zdarzenie z zadaniem, Suspend metoda uruchomione zadanie, powiadamianie zadania do wstrzymania.Gdy klient wznowi wykonanie run -czas silnika wywołania ResumeExecution Metoda zadań, które są zawieszone.

Wstrzymywanie i wznawianie wykonanie zadań obejmuje wstrzymywanie i wznawianie wątek wykonywania tego zadania.W kod zarządzany, możesz to zrobić za pomocą ManualResetEvent klasy w System.Threading obszar nazw.NET Framework.

Poniższy przykładowy kod ilustruje, zawieszenie lub wznowienie wykonywania zadań.Należy zauważyć, że Execute metoda został zmieniony z poprzedniego przykładowy kod i wątek wykonywania jest wstrzymana podczas wyzwalania punkt przerwania.

private ManualResetEvent m_suspended = new ManualResetEvent( true );
private ManualResetEvent m_canExecute = new ManualResetEvent( true );
private int   m_suspendRequired = 0;
private int   m_debugMode = 0;

public override DTSExecResult Execute( Connections connections, Variables variables, IDTSComponentEvents events, IDTSLogging log, DtsTransaction txn)
{
   // While a task is not executing, it is suspended.  
   // Now that we are executing,
   // change to not suspended.
   ChangeEvent(m_suspended, false);
   
   // Check for a suspend before doing any work, 
   // in case the suspend and execute calls
   // were initiated at virtually the same time.
   CheckAndSuspend();
   CheckAndFireBreakpoint( componentEvents, 1);
}
private void CheckAndSuspend()
{
   // Loop until we can execute.  
   // The loop is required rather than a simple If
   // because there is a time between the return from WaitOne and the
   // reset that we might receive another Suspend call.  
   // Suspend() will see that we are suspended
   // and return.  So we need to rewait.
   while (!m_canExecute.WaitOne(0, false))
   {
      ChangeEvent(m_suspended, true);
      m_canExecute.WaitOne();
      ChangeEvent(m_suspended, false);
   }
}
private void CheckAndFireBreakpoint(IDTSComponentEvents events, int breakpointID)
{
   // If the breakpoint is enabled, fire it.
   if (m_debugMode != 0 &&    this.bpm.IsBreakpointTargetEnabled(breakpointID))
   {
      //   Enter a suspend mode before firing the breakpoint.  
      //   Firing the breakpoint will cause the runtime 
      //   to call Suspend on this task.  
      //   Because we are blocked on the breakpoint, 
      //   we are suspended.
      ChangeEvent(m_suspended, true);
      events.OnBreakpointHit(this.bpm.GetBreakpointTarget(breakpointID));
      ChangeEvent(m_suspended, false);
   }
   // Check for a suspension for two reasons: 
   //   1. If we are at a point where we could fire a breakpoint, 
   //      we are at a valid suspend point.  Even if we didn't hit a
   //      breakpoint, the runtime may have called suspend, 
   //      so check for it.     
   //   2. Between the return from OnBreakpointHit 
   //      and the reset of the event, it is possible to have
   //      received a suspend call from which we returned because 
   //      we were already suspended.  We need to be sure it is okay
   //      to continue executing now.
   CheckAndSuspend();
}
static void ChangeEvent(ManualResetEvent e, bool shouldSet)
{
   bool succeeded;
   if (shouldSet)
      succeeded = e.Set();
   else
      succeeded = e.Reset();

   if (!succeeded)
      throw new Exception("Synchronization object failed.");
            
}
public bool SuspendRequired
{
   get   {return m_suspendRequired != 0;}
   set
   {
      // This lock is also taken by Suspend().  
      // Because it is possible for the package to be
      // suspended and resumed in quick succession, 
      // this property might be set before
      // the actual Suspend() call.  
      // Without the lock, the Suspend() might reset the canExecute
      // event after we set it to abort the suspension.
      lock (this)
      {
         Interlocked.Exchange(ref m_suspendRequired, value ? 1 : 0);
         if (!value)
            ResumeExecution();
      }
   }
}
public void ResumeExecution()
{
   ChangeEvent( m_canExecute,true );
}
public void Suspend()
{
   // This lock is also taken by the set SuspendRequired method.  
   // It prevents this call from overriding an 
   // aborted suspension.  See comments in set SuspendRequired.
   lock (this)
   {
      // If a Suspend is required, do it.
      if (m_suspendRequired != 0)
         ChangeEvent(m_canExecute, false);
   }
   // We can't return from Suspend until the task is "suspended".
   // This can happen one of two ways: 
   // the m_suspended event occurs, indicating that the execute thread
   // has suspended, or the canExecute flag is set, 
   // indicating that a suspend is no longer required.
   WaitHandle [] suspendOperationComplete = {m_suspended, m_canExecute};
   WaitHandle.WaitAny(suspendOperationComplete);
}
Private m_suspended As ManualResetEvent = New ManualResetEvent(True)
Private m_canExecute As ManualResetEvent = New ManualResetEvent(True)
Private m_suspendRequired As Integer = 0
Private m_debugMode As Integer = 0

Public Overrides Function Execute(ByVal connections As Connections, _
ByVal variables As Variables, ByVal events As IDTSComponentEvents, _
ByVal log As IDTSLogging, ByVal txn As DtsTransaction) As DTSExecResult

   ' While a task is not executing it is suspended.  
   ' Now that we are executing,
   ' change to not suspended.
   ChangeEvent(m_suspended, False)

   ' Check for a suspend before doing any work, 
   ' in case the suspend and execute calls
   ' were initiated at virtually the same time.
   CheckAndSuspend()
   CheckAndFireBreakpoint(componentEvents, 1)

End Function

Private Sub CheckAndSuspend()

   ' Loop until we can execute.  
   ' The loop is required rather than a simple if
   ' because there is a time between the return from WaitOne and the
   ' reset that we might receive another Suspend call.  
   ' Suspend() will see that we are suspended
   ' and return.  So we need to rewait.
   Do While Not m_canExecute.WaitOne(0, False)
              ChangeEvent(m_suspended, True)
              m_canExecute.WaitOne()
              ChangeEvent(m_suspended, False)
   Loop

End Sub

Private Sub CheckAndFireBreakpoint(ByVal events As IDTSComponentEvents, _
ByVal breakpointID As Integer)

   ' If the breakpoint is enabled, fire it.
   If m_debugMode <> 0 AndAlso Me.bpm.IsBreakpointTargetEnabled(breakpointID) Then
              '   Enter a suspend mode before firing the breakpoint.  
              '   Firing the breakpoint will cause the runtime 
              '   to call Suspend on this task.  
              '   Because we are blocked on the breakpoint, 
              '   we are suspended.
              ChangeEvent(m_suspended, True)
              events.OnBreakpointHit(Me.bpm.GetBreakpointTarget(breakpointID))
              ChangeEvent(m_suspended, False)
   End If

   ' Check for a suspension for two reasons: 
   '   1. If we are at a point where we could fire a breakpoint, 
   '         we are at a valid suspend point.  Even if we didn't hit a
   '         breakpoint, the runtime may have called suspend, 
   '         so check for it.   
   '   2. Between the return from OnBreakpointHit 
   '         and the reset of the event, it is possible to have
   '         received a suspend call from which we returned because 
   '         we were already suspended.  We need to be sure it is okay
   '         to continue executing now.
   CheckAndSuspend()

End Sub

Shared Sub ChangeEvent(ByVal e As ManualResetEvent, ByVal shouldSet As Boolean)

   Dim succeeded As Boolean
   If shouldSet Then
              succeeded = e.Set()
   Else
              succeeded = e.Reset()
   End If

   If (Not succeeded) Then
              Throw New Exception("Synchronization object failed.")
   End If
 
End Sub

Public Property SuspendRequired() As Boolean
   Get
               Return m_suspendRequired <> 0
  End Get
  Set
    ' This lock is also taken by Suspend().  
     '   Because it is possible for the package to be
     '   suspended and resumed in quick succession, 
     '   this property might be set before
     '   the actual Suspend() call.  
     '   Without the lock, the Suspend() might reset the canExecute
     '   event after we set it to abort the suspension.
              SyncLock Me
                         Interlocked.Exchange(m_suspendRequired,IIf(Value, 1, 0))
                         If (Not Value) Then
                                    ResumeExecution()
                         End If
              End SyncLock
   End Set
End Property

Public Sub ResumeExecution()
   ChangeEvent(m_canExecute,True)
End Sub

Public Sub Suspend()

   ' This lock is also taken by the set SuspendRequired method.  
   ' It prevents this call from overriding an 
   ' aborted suspension.  See comments in set SuspendRequired.
   SyncLock Me
   ' If a Suspend is required, do it.
              If m_suspendRequired <> 0 Then
                         ChangeEvent(m_canExecute, False)
              End If
   End SyncLock
   ' We can't return from Suspend until the task is "suspended".
   ' This can happen one of two ways: 
   ' the m_suspended event occurs, indicating that the execute thread
   ' has suspended, or the canExecute flag is set, 
   ' indicating that a suspend is no longer required.
   Dim suspendOperationComplete As WaitHandle() = {m_suspended, m_canExecute}
   WaitHandle.WaitAny(suspendOperationComplete)

End Sub
Ikona usług Integration Services (mała)Bieżąco z usług integracji

Najnowsze pliki do pobrania, artykuły, próbki i wideo firmy Microsoft, jak również wybranych rozwiązań ze Wspólnoty, odwiedź witrynę Integration Services strona na MSDN i TechNet:

Aby otrzymywać automatyczne powiadomienia dotyczące tych aktualizacji, zasubskrybuj źródła danych RSS dostępne na tej stronie.

Zobacz także

Zadania