"Значение не может быть нулевым" при вызове метода, украшенного [Autocomplete]
У меня есть приложение Windows Forms (.NET 3.5), которое развернуто с технологией ClickOnce и используется примерно 50-100 одновременными пользователями. Все они ориентированы на одну и ту же базу данных MS SQL (SQL SERVER 2008 R2), которая размещается снаружи.
Само приложение использует класс-оболочку для выполнения запросов к базе данных. Этот класс является производным от ServicedComponent и украшает его методы атрибутом [AutoComplete]. Ниже приведен пример:
[Serializable]
[Transaction(TransactionOption.Required, Isolation=TransactionIsolationLevel.ReadCommitted)]
public class CTxGreenfee374Processor: ServicedComponent
{
public CTxGreenfee374Processor() { }
[AutoComplete]
internal Season SaveSeason(CallContext callContext, Season season)
{
return new PGreenfee374Processor().SaveSeason(callContext, season);
}
}
В большинстве случаев этот подход работает как шарм. Но при вызове этого метода возникает много раз в день следующее исключение (конечно, есть подобные методы с этой конкретной проблемой):
System.ArgumentNullException
Value cannot be null.
Server stack trace:
at System.Threading.Monitor.Enter(Object obj)
at System.Data.ProviderBase.DbConnectionPool.TransactedConnectionPool.TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject)
at System.Data.ProviderBase.DbConnectionPool.TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject)
at System.Data.ProviderBase.DbConnectionInternal.CleanupConnectionOnTransactionCompletion(Transaction transaction)
at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
at System.Transactions.TransactionStateDelegatedCommitting.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStateDelegated.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.EnterpriseServices.TransactionProxy.Commit(Guid guid)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.EnterpriseServices.Thunk.Callback.DoCallback(Object otp, IMessage msg, IntPtr ctx, Boolean fIsAutoDone, MemberInfo mb, Boolean bHasGit)
at System.EnterpriseServices.ServicedComponentProxy.CrossCtxInvoke(IMessage reqMsg)
at System.EnterpriseServices.ServicedComponentProxy.Invoke(IMessage request)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at GOLFIT.BusinessProcess.Economics.CTxGreenfee374Processor.SaveSeason(CallContext callContext, Season season)
at GOLFIT.BusinessProcess.Economics.Greenfee374Processor.SaveSeason(CallContext callContext, Season season) in C:\Projekt\GOLFIT\DEVELOPMENTPROD374\BusinessProcess\GOLFIT.BusinessProcess.Economics\Greenfee374\Greenfee374Processor.cs:line 104
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at GOLFIT.BusinessProcess.Economics.Greenfee374Processor.SaveSeason(CallContext callContext, Season season)
at GOLFIT.WinGUI.Economics.FrmPrice374.Save(Boolean refresh).
Как вы можете видеть, метод SaveSeason в классе CTxGreenfee374Processor упоминается в исключении. Насколько я вижу, это последний след кода, который я написал.
Единственная подсказка - исключение связано с атрибутом [AutoComplete] и / или производным классом ServicedComponent. Этот вывод основан на том, что я проверил недопустимые входные параметры и что ни один код внутри метода не выполняется перед исключением. И я предполагаю, что и класс ServicedComponent, и атрибут [AutoComplete] выполняют некоторую логику перед выполнением блока метода.
Мне не удалось воссоздать это исключение при отладке из-за непоследовательного появления этого исключения. Поэтому мне пришлось зависеть от логов из производственного приложения.
Если у кого-то возникнет идея относительно этой проблемы, мы будем очень признательны!