Я столкнулся с той же проблемой «Код ошибки: 0xC0048021» и решил ее.
Я установил эту версию SSDT здесь https://msdn.microsoft.com/en-us/mt429383
Затем в решении SSDT explorer щелкните правой кнопкой мыши Project, перейдите в Свойства -> Свойства конфигурации -> TargetServerVersion = SQL SERVER 2014
Затем в проводнике SSDT щелкните правой кнопкой мыши Project, перейдите в Properties -> Configuration Свойства -> Отладка -> Run64BitRuntime = False
Ссылка на эту ссылку http://blogs.msdn.com/b/ssis/archive/2016/03/03/what-s -new-for-ssis-2016-rc0.aspx
Согласно исходному коду ThrowHelper.cs основная цель - уменьшить размер кода JITted. Ниже приведена прямая копия вставки по ссылке:
// This file defines an internal class used to throw exceptions in BCL code.
// The main purpose is to reduce code size.
//
// The old way to throw an exception generates quite a lot IL code and assembly code.
// Following is an example:
// C# source
// throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
// IL code:
// IL_0003: ldstr "key"
// IL_0008: ldstr "ArgumentNull_Key"
// IL_000d: call string System.Environment::GetResourceString(string)
// IL_0012: newobj instance void System.ArgumentNullException::.ctor(string,string)
// IL_0017: throw
// which is 21bytes in IL.
//
// So we want to get rid of the ldstr and call to Environment.GetResource in IL.
// In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the
// argument name and resource name in a small integer. The source code will be changed to
// ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);
//
// The IL code will be 7 bytes.
// IL_0008: ldc.i4.4
// IL_0009: ldc.i4.4
// IL_000a: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
// IL_000f: ldarg.0
//
// This will also reduce the Jitted code size a lot.
Посмотрите на то, что делает ThrowHelper. Это получает ресурсы и материал для сообщений об ошибках. В этом конкретном экземпляре нет никакого текста ошибки, таким образом, кажется, что это бесполезно, но их шаблон, вероятно, требует его, таким образом, разработчик, который записал это, следовал за шаблоном как, он или она должен.
Другим интересным аспектом является производительность. Интересно достаточно метод, который содержит throw
оператор, может быть медленнее, даже если исключение не выдается просто, потому что JIT предпочитает не встраивать такие методы (возможно, к лучшему удобочитаемость стека вызовов). Рассмотрите следующий пример:
private class TestClass
{
internal int RegularThrow(int value)
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
return value + 1;
}
internal int ThrowByHelper(int value)
{
if (value < 0)
Throw.ArgumentOutOfRangeException(Argument.value); // Argument is an enum
return value + 1;
}
}
Результаты проверки производительности на моем компьютере:
(См., что источник связывается наряду с некоторыми комментариями ниже)
1. ThrowByHelper: average time: 5,24 ms
#1 5,26 ms
#2 5,16 ms <---- Best
#3 5,31 ms <---- Worst
Worst-Best difference: 0,16 ms (3,02%)
2. RegularThrow: average time: 23,51 ms (+18,27 ms / 448,40%)
#1 23,46 ms
#2 23,42 ms <---- Best
#3 23,65 ms <---- Worst
Worst-Best difference: 0,22 ms (0,95%)
Значение, метод с явным throw
оператор был в 4.5 раза медленнее! Но...
Интересные Наблюдения:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
атрибут, хотя это ничего не гарантирует. Например, во встраивании Скрипки.NET, кажется, обычно отключается, следовательно оба пути имеют эффективно ту же производительность. Посмотрите исходный код и совершенно другие результаты здесь . ArgumentException
предотвращенное встраивание (не используя атрибутов). По крайней мере, бросок NotSupportedException
или InvalidOperationException
непосредственно не влиял на производительность негативно. Избыточная/недостижимая проблема кода и анализаторы кода:
избыточное return
оператора можно избежать путем определения некоторых универсальных перегрузок в ThrowHelper
:
// for regular usage:
internal static void ArgumentException(Argument arg, string message) => throw new...
// for expression usage:
internal static T ArgumentException<T>(Argument arg, string message) => throw new...
последний может использоваться в return
оператор, может сэкономить break
в [1 115] блоки и запускающийся с C# 7.0, он может использоваться тот же путь в качестве выражений отсеивания:
return value >= 0 ? value + 1 : Throw.ArgumentOutOfRangeException<int>(Argument.value);
Другая проблема - то, что ReSharper и FxCop не распознают участников помощника броска и могут начать испускать ложные положительные предупреждения. Для ReSharper мы можем использовать эти ContractAnnotation
атрибут:
// prevents PossibleNullReferenceException, AssignNullToNotNullAttribute and similar false alarms
[ContractAnnotation("=> halt")]
internal static void ArgumentException(Argument arg, string message) => throw new...
К сожалению для FxCop я не нашел аналогичное решение (и эти [DoesNotReturn]
, атрибут, по-видимому, не работает), таким образом, необходимо использовать #pragma warning disable
или эти SuppressMessage
атрибут для подавления CA1031, CA1062 и их друзей.