Özel görev hata ayıklama için desteği ekleme
The Integration Services run-saat engine enables packages, tasks, and other types of containers to be suspended during execution by using breakpoints. Kesme noktaları kullanımını gözden geçirme ve uygulama ya da görevler düzgün çalışmasını engelleyen hataları düzeltmek sağlar.Kesme noktası mimarisi çalışma-değerlendirmek istemci sağlar saat görev işlemi askıya alınmış durumdayken yürütülmesinin tanımlı noktalarda paketteki nesneleri değeri.
Özel görev geliştiriciler bu mimariye kullanarak özel bir kesme noktası hedefleri oluşturmak için kullanabileceğiniz IDTSBreakpointSite arabirim ve onun üst arabirimi IDTSSuspend. The IDTSBreakpointSite arabirim defines the interaction between the run-saat engine and the task for creating and managing custom kesme noktası sites or targets. The IDTSSuspend arabirim provides methods and properties that are called by the run-saat engine to notify the task to suspend or resume its execution.
Kesme noktası site veya hedef bir görevin yürütülmesine burada işlemi askıya alınır.Kullanılabilir bir kesme noktası siteler, kullanıcıların seçmesi Kesme noktalarını küme iletişim kutusu.Örneğin, varsayılan kesme noktası seçeneklere ek olarak, döngü Foreach kapsayıcı "Her döngü tekrarında başında kesme" seçeneği sunar.
Görev yürütülürken bir kesme noktası hedef ulaştığında, kesme etkinleştirilmiş olup olmadığını belirlemek için kesme noktası hedef olarak değerlendirilir.Bu, kullanıcının bu kesme noktası noktası noktasında durdurmak için yürütme istediğini gösterir.kesme noktası noktası etkinleştirilmişse, görevi oluşturan OnBreakpointHit(IDTSBreakpointSite, BreakpointTarget) Olay çalışma-saat altyapısı. Çalışma-saat çağırarak, altyapısı olaya yanıt Suspend pakette çalışmakta olan görev yöntem. Çalışma zamanı aradığında, görevin yürütülmesini sürdürür ResumeExecution askıya alınan görev yöntem.
Kesme noktaları kullanan görevler yine de uygulamanız IDTSBreakpointSite ve IDTSSuspend arabirimler. Bu paketin diğer nesneleri oluşturmak için görevi doğru askıya sağlar. OnBreakpointHit(IDTSBreakpointSite, BreakpointTarget) olaylar.
IDTSBreakpointSite arabirim ve BreakpointManager
Görevleri, arayan kesme noktası hedeflerini oluşturma CreateBreakpointTarget(Int32, String) yöntem BreakpointManager, parametre olarak bir tamsayı KIMLIĞI ve dize açıklama sağlar. Görev noktasının bir kesme noktası hedef içeren kodunda ulaştığında, kesme noktası hedef kullanarak değerlendirir IsBreakpointTargetEnabled(Int32) Bu kesme noktası'nın etkin olup olmadığını belirlemek için yöntem. If true, görevin çalışma-bildirir saat tarafından Yükseltme motoru OnBreakpointHit(IDTSBreakpointSite, BreakpointTarget) olay.
The IDTSBreakpointSite arabirim defines a single yöntem, AcceptBreakpointManager(BreakpointManager), which is called by the run-saat engine during task creation. Bu yöntemin bir parametresi olarak sağlar BreakpointManager Nesne daha sonra görevi tarafından oluşturmak ve kendi kesme noktaları yönetmek için kullanılır. Görevleri depolamalısınız BreakpointManager yerel kullanım sırasında Validate ve Execute yöntemleri.
Aşağıdaki örnek kodu kullanarak bir kesme noktası hedef oluşturulması gösterilmiştir BreakpointManager. Örnek çağrı OnBreakpointHit(IDTSBreakpointSite, BreakpointTarget) yöntem, olay yükseltmek için.
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
IDTSSuspend arabirim
The IDTSSuspend arabirim defines the methods that are called by the run-saat engine when it pauses or resumes execution of a task. The IDTSSuspend arabirim is implemented by the IDTSBreakpointSite arabirim, and its Suspend and ResumeExecution methods are usually overridden by the custom task. Zaman çalışma-saat altyapısı aldığı bir OnBreakpointHit Olay görevden, onu çağıran Suspend Görevleri duraklatma bildiren, çalışan her görevi yöntem. Istemci yürütülmesine devam ettiğinde, çalışma zamanı altyapısı çağırır ResumeExecution askıya alınmış görevleri yöntem.
Askıya alma ve görevin yürütülmesine devam ettiriliyor duraklatma ve görevin yürütme iş parçacığı yeniden başlatma gerektirir.Yönetilen kodda kullanarak bunu ManualResetEvent sınıf System.Threading .NET Framework'ün ad alanı.
Aşağıdaki kod örneği, Askı ve görev yürütülmesinin sürdürme gösterir.Fark Execute yöntem önceki kod örneğini değişti ve yürütme iş parçacığı kesme noktası noktası tetikleme, duraklatıldı.
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
|