【问题标题】:Why does FireError fail in C# 2012, but works in VB, while FireInformation works in both?为什么 FireError 在 C# 2012 中失败,但在 VB 中有效,而 FireInformation 在两者中都有效?
【发布时间】:2015-03-06 20:21:23
【问题描述】:

我在 Visual Studio 2014 中有一个 SSIS 包,如果有任何记录穿过第 3 方转换的特定路径,我想在脚本组件中引发错误。我想要在 C# 2012 中执行此操作,但 FireError 方法给出了错误:

'Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSComponentMetaData100.FireError(int, string, string, string, int, out bool)'的最佳重载方法匹配有一些无效参数

当我尝试这样做时:

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

但如果我将 FireError 更改为 FireInformation,它会编译并运行——当然,除了我需要引发错误,而不是信息事件。

另外,如果我使用 Visual Basic 而不是 C#:

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

我的意思是,字面上完全一样的东西,但用不同的语言,它工作得很好。 VB 也适用于 FireInformation。

显然我可以通过使用 VB 来解决我当前的问题,但是有人可以告诉我为什么会这样吗?这似乎是 C# 的一个特定问题。作为证据,我们在 MSDN 上有这个:https://msdn.microsoft.com/en-us/library/ms136031.aspx

FireError 的脚本组件版本是 唯一 八个没有 C# VB 版本的示例(日志记录的格式很差,但它们都是那里)。

我想知道是否有一个调试器配置可能会以奇怪的方式运行 C# 代码,正如this stackoverflow question 回答的那样,但我得到的错误是在设计时——Visual Studio 会出现早期的“无效参数”错误在我编译之前,它就知道有问题了。

想法?

【问题讨论】:

    标签: c# vb.net visual-studio ssis sql-server-2012


    【解决方案1】:

    您可能会混淆从脚本组件(数据流任务)和脚本任务(控制流)触发错误和信息事件的相似但不同的语法。 Component的intellisense表示参数是pbCancel,而fireAgain对应的是Information Task的参数。

    脚本组件

    C# 脚本组件示例

    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 组件

    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
    

    没有必要明确指定参数是通过引用,因为这似乎是在定义中完成的,而 C# 要求在调用时也指定它。 ByRef vs ByVal Clarification

    脚本任务

    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
    

    总结

    • C# 要求您指定 refout 关键字。它们不是同义词
    • VB 让你做任何事
    • 组件中的错误事件有一个取消参数

    【讨论】:

    • 所以,我得到了 ref 和 out 的效用;我认为您的第三个注意事项是“组件中的错误事件具有取消参数”对于为什么布尔值必须是“out”参数而不是 ref 很重要;也就是说,我很欣赏如何修复它,但是为什么这两个函数(FireInformation 和 FireError)在这方面有所不同?
    • 另外,我仍然认为我链接到的 Microsoft 文档在该主题上是神秘的,所以我很好奇是否有人知道原因。但再次感谢!
    【解决方案2】:

    您在 C# 中通过 ref 传递它,而不是 out。我认为 VB.NET 不需要这些关键字。

    【讨论】:

    • 那么,是否有正确的语法可以让 FireError 在我缺少的 C# 中工作?
    • 我明白了; billinkc 有一个很好的例子。仍然不清楚为什么 FireError 需要一个“out”变量;我想您可以继续在 FireInformation 调用中更新布尔值,但错误需要标志保持静态......仍然不完全清楚原因。是否有 FireError
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2015-02-01
    相关资源
    最近更新 更多