Why does FireError fail in C# 2012, but works in V

2019-02-20 13:10发布

问题:

I have an SSIS package in Visual Studio 2014, and I want to raise an error in a Script Component if any records traverse a particular path out of a 3rd party transformation. I WANT to do this in C# 2012, but the FireError method gives an error:

The best overloaded method match for 'Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSComponentMetaData100.FireError(int, string, string, string, int, out bool)' has some invalid arguments

When I try to do this:

    bool fireAgain = false;
    IDTSComponentMetaData100 myMetaData;
    myMetaData = this.ComponentMetaData;
    myMetaData.FireError(0, "Script Component", "Invalid Records", string.Empty, 0, ref fireAgain);

but if I change FireError to FireInformation, it compiles and works -- except of course I need an error raised, not an informative event.

Also, if I use Visual Basic instead of C# as so:

    Dim pbFireAgain As Boolean = False
    Dim myMetaData As IDTSComponentMetaData100
    myMetaData = Me.ComponentMetaData
    myMetaData.FireError(0, "Script Component", "Invalid Records", String.Empty, 0, pbFireAgain)

Which is, I mean, literally the same exact thing but in a different language, it works fine. VB also works with FireInformation.

Obviously I can solve my immediate problem by using VB, but can someone tell me WHY this is this way? It seems like a specific issue with C#. As evidence, we have this on MSDN: https://msdn.microsoft.com/en-us/library/ms136031.aspx

Where the Script Component version of FireError is the only of eight examples to not have C# and VB versions (the logging one is poorly formatted, but they're both there).

I'm wondering if there's a debugger configuration that threatens to run C# code in an odd way, as this stackoverflow question answered, but the error I get is at design time -- Visual Studio springs the earlier "invalid arguments" error before I compile, so it knows something is off.

Thoughts?

回答1:

You may be confusing the similar but different syntax for firing error vs information events from Script Components (data flow task) versus Script Tasks (control flow). The intellisense for Component indicates that the parameter is pbCancel whereas the fireAgain corresponds to the Information Task's parameter.

Script Component

C# Script Component example

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    bool cancel = false;
    bool fireAgain = false;
    this.ComponentMetaData.FireInformation(0, "My sub", "info", string.Empty, 0, ref fireAgain);
    this.ComponentMetaData.FireError(0, "My sub", "error", string.Empty, 0, out cancel);
}

VB Component

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    Dim cancel As Boolean
    Dim fireAgain As Boolean
    Me.ComponentMetaData.FireInformation(0, "my sub", "info", String.Empty, 0, fireAgain)
    Me.ComponentMetaData.FireError(0, "I hate vb", "Error", String.Empty, 0, cancel)
End Sub

There's no need to explicitly specify that a parameter is By Reference since that appears to be done in the definition versus the C# requirement to specify it also on invocation. ByRef vs ByVal Clarification

Script Task

C#

    public void Main()
    {
        bool fireAgain = false;
        this.Dts.Events.FireInformation(0, "my sub", "info", string.Empty, 0, ref fireAgain);
        // Note, no cancel available
        this.Dts.Events.FireError(0, "my sub", "error", string.Empty, 0);
    }

VB

Public Sub Main()
    Dim fireAgain As Boolean = False
    Me.Dts.Events.FireInformation(0, "my sub", "info desc", String.Empty, 0, fireAgain)
    Me.Dts.Events.FireError(0, "my sub", "error desc", String.Empty, 0)

    Dts.TaskResult = ScriptResults.Success
End Sub

Summary

  • C# requires you to specify ref and out keywords. They are not synonyms
  • VB lets you do whatever
  • Error event in Components have a cancel parameter


回答2:

You are passing it by ref, not out, in your C#. I don't think VB.NET needs those keywords.