Exemplo n.º 1
0
        public static IObservable <object> PollValues(this IAdsConnection connection, string instancePath, Type type, int[] args, IObservable <Unit> trigger, Func <Exception, object> errorHandler)
        {
            string[]            symbolPaths = new string[] { instancePath };
            DisposableHandleBag bag         = new DisposableHandleBag(connection, symbolPaths);
            Func <Unit, object> func        = delegate(Unit o) {
                try
                {
                    return(connection.ReadAny(0xf005, bag.GetHandle(instancePath), type, args));
                }
                catch (Exception exception)
                {
                    if (errorHandler == null)
                    {
                        throw;
                    }
                    return(errorHandler(exception));
                }
            };
            Action action = delegate {
                bag.Dispose();
                bag = null;
            };

            return(Observable.Finally <object>(Observable.Select <Unit, object>(trigger, func), action));
        }
Exemplo n.º 2
0
        internal AdsSymbolLoader(IAdsConnection connection, SymbolLoaderSettings settings, IAccessorRawValue accessor, ISession session, SymbolUploadInfo symbolsInfo)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            if (accessor == null)
            {
                throw new ArgumentNullException("accessor");
            }
            if (symbolsInfo == null)
            {
                throw new ArgumentNullException("symbolsInfo");
            }
            ISymbolFactory symbolFactory = null;

            this._connection       = connection;
            this._symbolUploadInfo = symbolsInfo;
            symbolFactory          = (settings.SymbolsLoadMode != SymbolsLoadMode.DynamicTree) ? ((ISymbolFactory) new TwinCAT.Ads.TypeSystem.SymbolFactory(settings.NonCachedArrayElements)) : ((ISymbolFactory) new DynamicSymbolFactory(new TwinCAT.Ads.TypeSystem.SymbolFactory(settings.NonCachedArrayElements), settings.NonCachedArrayElements));
            this._settings         = settings;
            AdsBinder binder = new AdsBinder(this._connection.Address, this, symbolFactory, this.UseVirtualInstances);

            this._symbolFactorServices = new SymbolFactoryServices(binder, symbolFactory, accessor, session);
            symbolFactory.Initialize(this._symbolFactorServices);
            this._rootNamespace = this._connection.Address.ToString();
            this._namespaces    = new NamespaceCollection();
        }
Exemplo n.º 3
0
        protected SumCommand(IAdsConnection connection, SumCommandMode commandMode, SumAccessMode readWriteMode)
        {
            this.ig          = AdsReservedIndexGroups.SumCommandRead;
            this.connection  = connection;
            this.mode        = readWriteMode;
            this.commandMode = commandMode;
            switch (commandMode)
            {
            case SumCommandMode.Read:
                this.ig = AdsReservedIndexGroups.SumCommandRead;
                return;

            case SumCommandMode.Write:
                this.ig = AdsReservedIndexGroups.SumCommandWrite;
                return;

            case SumCommandMode.ReadWrite:
                this.ig = AdsReservedIndexGroups.SumCommandReadWrite;
                return;

            case SumCommandMode.AddDeviceNotification:
                this.ig = AdsReservedIndexGroups.SumCommandAddDevNote;
                return;

            case SumCommandMode.DeleteDeviceNotification:
                this.ig = AdsReservedIndexGroups.SumCommandDelDevNote;
                return;
            }
            throw new NotImplementedException();
        }
Exemplo n.º 4
0
 public DataTypeInfoTable(IAdsConnection adsClient, Encoding encoding, int targetPointerSize)
 {
     this._adsClient         = adsClient;
     this._encoding          = encoding;
     this._targetPointerSize = targetPointerSize;
     this.Clear();
 }
Exemplo n.º 5
0
        public static IObservable <SymbolNotification> WhenNotification(this IAdsConnection client, ISymbol symbol, NotificationSettings settings)
        {
            if (symbol == null)
            {
                throw new ArgumentNullException("symbol");
            }
            if (symbol == null)
            {
                throw new ArgumentOutOfRangeException("Symbol is not an IValueSymbol", "symbol");
            }
            List <ISymbol> symbols = new List <ISymbol> {
                symbol
            };
            IDisposableSymbolHandleBag bag = null;
            IAccessorValueFactory      fac = ((IAccessorValue)(symbol as IValueSymbol).ValueAccessor).ValueFactory;
            object userData = new object();

            return(Observable.Select <EventPattern <AdsNotificationEventArgs>, SymbolNotification>(Observable.Where <EventPattern <AdsNotificationEventArgs> >(Observable.FromEventPattern <AdsNotificationEventHandler, AdsNotificationEventArgs>(delegate(AdsNotificationEventHandler h) {
                client.AdsNotification += h;
                bag = new DisposableNotificationHandleBag(client, symbols, settings, userData);
            }, delegate(AdsNotificationEventHandler h) {
                bag.Dispose();
                bag = null;
                client.AdsNotification -= h;
            }), ev => bag.Contains((uint)ev.get_EventArgs().NotificationHandle)), ev => new SymbolNotification(ev.get_EventArgs(), bag.GetSymbol((uint)ev.get_EventArgs().NotificationHandle), fac)));
        }
Exemplo n.º 6
0
 internal AdsConnectionRestore(AdsValueAccessorBase accessor)
 {
     if (accessor == null)
     {
         throw new ArgumentNullException("connection");
     }
     if (accessor.AutomaticReconnection)
     {
         this.connection = (IAdsConnection)accessor.Session.Connection;
         if (this.connection == null)
         {
             throw new ArgumentException("accessor");
         }
         if (this.connection == null)
         {
             throw new ClientNotConnectedException();
         }
         if (!this.connection.IsConnected)
         {
             if (this.connection.Session == null)
             {
                 throw new ClientNotConnectedException();
             }
             this.connection          = (IAdsConnection)this.connection.Session.Connect();
             this.disconnectOnDispose = true;
         }
     }
 }
Exemplo n.º 7
0
        public static IObservable <SymbolNotification> WhenNotification(this IAdsConnection client, ISymbolCollection symbols, NotificationSettings settings)
        {
            if (symbols == null)
            {
                throw new ArgumentNullException("symbols");
            }
            ISymbol local1 = Enumerable.FirstOrDefault <ISymbol>(symbols);

            if (local1 == null)
            {
                throw new ArgumentOutOfRangeException("Symbols list is empty!", "symbols");
            }
            IValueSymbol symbol = local1 as IValueSymbol;

            if (symbol == null)
            {
                throw new ArgumentOutOfRangeException("Symbols in list are not IValueSymbol", "symbols");
            }
            IAccessorValueFactory      valueFactory = symbol.ValueAccessor.ValueFactory;
            IDisposableSymbolHandleBag bag          = null;
            object userData = new object();

            return(Observable.Where <SymbolNotification>(Observable.Select <EventPattern <AdsNotificationEventArgs>, SymbolNotification>(Observable.Where <EventPattern <AdsNotificationEventArgs> >(Observable.FromEventPattern <AdsNotificationEventHandler, AdsNotificationEventArgs>(delegate(AdsNotificationEventHandler h) {
                client.AdsNotification += h;
                bag = new DisposableNotificationHandleBag(client, symbols, settings, userData);
            }, delegate(AdsNotificationEventHandler h) {
                bag.Dispose();
                bag = null;
                client.AdsNotification -= h;
            }), ev => bag.Contains((uint)ev.get_EventArgs().NotificationHandle)), ev => new SymbolNotification(ev.get_EventArgs(), bag.GetSymbol((uint)ev.get_EventArgs().NotificationHandle), valueFactory)), s => symbols.Contains(s.Symbol)));
        }
 public DisposableNotificationExHandleBag(IAdsConnection client, IDictionary <string, AnyTypeSpecifier> dict, NotificationSettings settings, object userData) : base(client)
 {
     if (dict == null)
     {
         throw new ArgumentNullException("dict");
     }
     if (dict.Count == 0)
     {
         throw new ArgumentOutOfRangeException("dict");
     }
     base.handleDict      = new SumHandleList();
     base.validHandleDict = new Dictionary <string, uint>();
     foreach (KeyValuePair <string, AnyTypeSpecifier> pair in dict)
     {
         uint             handle    = 0;
         AnyTypeSpecifier specifier = pair.Value;
         Type             tp        = null;
         int[]            args      = null;
         specifier.GetAnyTypeArgs(out tp, out args);
         AdsErrorCode errorCode = client.TryAddDeviceNotificationEx(pair.Key, settings, userData, tp, args, out handle);
         base.handleDict.Add(new SumHandleInstancePathEntry(pair.Key, handle, errorCode));
         if (errorCode == AdsErrorCode.NoError)
         {
             base.validHandleDict.Add(pair.Key, handle);
         }
     }
 }
Exemplo n.º 9
0
        internal static IAccessorValue createValueAccessor(IAdsConnection connection, SymbolLoaderSettings settings)
        {
            IAccessorValue        value2       = null;
            AdsValueAccessor      inner        = null;
            IAccessorValueFactory valueFactory = null;

            if (settings.SymbolsLoadMode == SymbolsLoadMode.DynamicTree)
            {
                valueFactory = new DynamicValueFactory(settings.ValueCreation);
                inner        = new AdsValueAccessor(connection, settings.ValueAccessMode, valueFactory, NotificationSettings.Default);
                value2       = new DynamicValueAccessor(inner, valueFactory, settings.ValueCreation);
            }
            else
            {
                valueFactory = new ValueFactory(settings.ValueCreation);
                inner        = new AdsValueAccessor(connection, settings.ValueAccessMode, valueFactory, NotificationSettings.Default);
                value2       = inner;
            }
            IAccessorValueFactory2 factory2 = valueFactory as IAccessorValueFactory2;

            if (valueFactory != null)
            {
                factory2.SetValueAccessor(value2);
            }
            inner.AutomaticReconnection = settings.AutomaticReconnection;
            return(value2);
        }
Exemplo n.º 10
0
        public SumAddNotifications(IAdsConnection connection, uint[] variableHandles, int[] lengths, NotificationSettings settings, AdsStream stream) : base(connection, TwinCAT.Ads.SumCommand.SumCommand.SumCommandMode.AddDeviceNotification, TwinCAT.Ads.SumCommand.SumCommand.SumAccessMode.ValueByHandle)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }
            if (variableHandles == null)
            {
                throw new ArgumentNullException("variableHandles");
            }
            if (lengths == null)
            {
                throw new ArgumentNullException("lengths");
            }
            if (variableHandles.Length != lengths.Length)
            {
                throw new ArgumentException("Handles/lenghts mismatch!");
            }
            int num = Enumerable.Max(lengths);

            if (stream.Length < num)
            {
                throw new ArgumentException("Notification Buffer/Stream is to small");
            }
            this._connection      = connection;
            this._variableHandles = variableHandles;
            this._variableLengths = lengths;
            this._settings        = settings;
            base.sumEntities      = this.CreateSumEntityInfos();
        }
        public DisposableNotificationHandleBag(IAdsConnection client, IEnumerable <ISymbol> symbols, NotificationSettings settings, object userData) : base(client)
        {
            if (symbols == null)
            {
                throw new ArgumentNullException("dict");
            }
            int length = Enumerable.Sum <ISymbol>(symbols, s => s.ByteSize);

            this._stream           = new AdsStream(length);
            base.handleDict        = new SumHandleList();
            this._handleSymbolDict = new Dictionary <uint, ISymbol>();
            base.validHandleDict   = new Dictionary <string, uint>();
            int offset = 0;

            foreach (ISymbol symbol in symbols)
            {
                uint         handle    = 0;
                int          byteSize  = symbol.ByteSize;
                AdsErrorCode errorCode = client.TryAddDeviceNotification(symbol.InstancePath, this._stream, offset, byteSize, settings, userData, out handle);
                base.handleDict.Add(new SumHandleInstancePathEntry(symbol.InstancePath, handle, errorCode));
                if (errorCode == AdsErrorCode.NoError)
                {
                    base.validHandleDict.Add(symbol.InstancePath, handle);
                    this._handleSymbolDict.Add(handle, symbol);
                }
                offset += byteSize;
            }
        }
Exemplo n.º 12
0
 protected DisposableHandleBag(IAdsConnection client)
 {
     if (client == null)
     {
         throw new ArgumentNullException("client");
     }
     this.connection = client;
 }
Exemplo n.º 13
0
        public static IObservable <object> WhenNotification(this IAdsConnection connection, string instancePath, Type type, NotificationSettings settings)
        {
            Dictionary <string, AnyTypeSpecifier> symbols = new Dictionary <string, AnyTypeSpecifier>();
            AnyTypeSpecifier specifier = new AnyTypeSpecifier(type);

            symbols.Add(instancePath, specifier);
            return(Observable.Select <NotificationEx, object>(connection.WhenNotificationEx(symbols, settings, null), n => n.Value));
        }
Exemplo n.º 14
0
 private void Dispose(bool disposing)
 {
     if (disposing)
     {
         this.Cleanup();
         this._adsClient = null;
     }
 }
Exemplo n.º 15
0
 public SumHandleWrite(IAdsConnection connection, IDictionary <uint, Type> handleTypeDict) : base(connection, TwinCAT.Ads.SumCommand.SumCommand.SumAccessMode.ValueByHandle)
 {
     this._converter  = PrimitiveTypeConverter.Default;
     base.sumEntities = new List <SumDataEntity>();
     foreach (KeyValuePair <uint, Type> pair in handleTypeDict)
     {
         base.sumEntities.Add(new HandleSumWriteAnyEntity(pair.Key, pair.Value, this._converter));
     }
 }
Exemplo n.º 16
0
 public SumHandleWrite(IAdsConnection connection, uint[] serverHandles, Type[] valueTypes) : base(connection, TwinCAT.Ads.SumCommand.SumCommand.SumAccessMode.ValueByHandle)
 {
     this._converter  = PrimitiveTypeConverter.Default;
     base.sumEntities = new List <SumDataEntity>();
     for (int i = 0; i < serverHandles.Length; i++)
     {
         base.sumEntities.Add(new HandleSumWriteAnyEntity(serverHandles[i], valueTypes[i], this._converter));
     }
 }
Exemplo n.º 17
0
        public static IObservable <AdsState> PollAdsState(this IAdsConnection client, IObservable <Unit> trigger)
        {
            Func <Unit, AdsState> func = delegate(Unit o) {
                StateInfo info;
                client.TryReadState(out info);
                return(info.AdsState);
            };

            return(Observable.Select <Unit, AdsState>(trigger, func));
        }
Exemplo n.º 18
0
        public static IObservable <NotificationEx> WhenNotification(this IAdsConnection connection, IDictionary <string, Type> symbols, NotificationSettings settings, object userData)
        {
            Dictionary <string, AnyTypeSpecifier> dictionary = new Dictionary <string, AnyTypeSpecifier>();

            foreach (KeyValuePair <string, Type> pair in symbols)
            {
                dictionary.Add(pair.Key, new AnyTypeSpecifier(pair.Value));
            }
            return(connection.WhenNotificationEx(dictionary, settings, userData));
        }
Exemplo n.º 19
0
 internal AdsValueAccessor(IAdsConnection connection, ValueAccessMode accessMethod, IAccessorValueFactory valueFactory, NotificationSettings defaultSettings) : base(valueFactory, connection, defaultSettings)
 {
     this._converter                  = new DynamicValueConverter();
     this._syncNotification           = new object();
     this._accessMethod               = ValueAccessMode.IndexGroupOffsetPreferred;
     this._notificationTable          = new AdsNotificationCache();
     this._notificationStream         = new AdsStream();
     this._address                    = connection.Address;
     this._accessMethod               = accessMethod;
     base._notificationSettings       = defaultSettings;
     connection.AdsNotification      += new AdsNotificationEventHandler(this.adsClient_AdsNotification);
     connection.AdsNotificationError += new AdsNotificationErrorEventHandler(this.adsClient_AdsNotificationError);
 }
Exemplo n.º 20
0
        internal static SymbolUploadInfo readSymbolUploadInfo(IAdsConnection connection)
        {
            SymbolUploadInfo uploadInfo   = null;
            AdsErrorCode     adsErrorCode = AdsSymbolLoader.loadUploadInfo(connection, TimeSpan.FromMilliseconds((double)connection.Timeout), out uploadInfo);

            if (adsErrorCode != AdsErrorCode.NoError)
            {
                AdsErrorException ex = AdsErrorException.Create(adsErrorCode);
                Module.Trace.TraceWarning("Could not load Symbol Upload info", ex);
                uploadInfo = new SymbolUploadInfo();
            }
            return(uploadInfo);
        }
Exemplo n.º 21
0
 internal SymbolInfoTable(IAdsConnection adsClient, Encoding symbolEncoding, int targetPointerSize)
 {
     if (adsClient == null)
     {
         throw new ArgumentNullException("adsClient");
     }
     if (symbolEncoding == null)
     {
         throw new ArgumentNullException("symbolEncoding");
     }
     this._adsClient     = adsClient;
     this._symbolTable   = new Dictionary <string, TcAdsSymbol>(StringComparer.OrdinalIgnoreCase);
     this._datatypeTable = new DataTypeInfoTable(adsClient, symbolEncoding, targetPointerSize);
     this._encoding      = symbolEncoding;
 }
Exemplo n.º 22
0
 public SumDeleteNotifications(IAdsConnection connection, uint[] notificationHandles) : base(connection, TwinCAT.Ads.SumCommand.SumCommand.SumCommandMode.DeleteDeviceNotification, TwinCAT.Ads.SumCommand.SumCommand.SumAccessMode.ReleaseHandle)
 {
     if (connection == null)
     {
         throw new ArgumentNullException("connection");
     }
     if (notificationHandles == null)
     {
         throw new ArgumentNullException("notificationHandles");
     }
     this._notificationHandles = notificationHandles;
     base.sumEntities          = new List <SumDataEntity>();
     for (int i = 0; i < notificationHandles.Length; i++)
     {
         base.sumEntities.Add(new NotificationHandleReleaseSumEntity(notificationHandles[i]));
     }
 }
Exemplo n.º 23
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         IAdsConnection connection = this.Connection;
         if (connection != null)
         {
             connection.AdsNotification      -= new AdsNotificationEventHandler(this.adsClient_AdsNotification);
             connection.AdsNotificationError -= new AdsNotificationErrorEventHandler(this.adsClient_AdsNotificationError);
         }
         if (this._notificationStream != null)
         {
             this._notificationStream.Close();
         }
         this._notificationStream = null;
     }
 }
Exemplo n.º 24
0
 public static IObservable <ValueChangedArgs> WhenValueChangedAnnotated(this IAdsConnection connection, IEnumerable <ISymbol> symbols) =>
 Observable.Select <EventPattern <ValueChangedArgs>, ValueChangedArgs>(Observable.FromEventPattern <EventHandler <ValueChangedArgs>, ValueChangedArgs>(delegate(EventHandler <ValueChangedArgs> h) {
     using (IEnumerator <ISymbol> enumerator = symbols.GetEnumerator())
     {
         while (enumerator.MoveNext())
         {
             ((IValueSymbol)enumerator.Current).ValueChanged += h;
         }
     }
 }, delegate(EventHandler <ValueChangedArgs> h) {
     using (IEnumerator <ISymbol> enumerator = symbols.GetEnumerator())
     {
         while (enumerator.MoveNext())
         {
             ((IValueSymbol)enumerator.Current).ValueChanged -= h;
         }
     }
 }), ev => ev.get_EventArgs());
Exemplo n.º 25
0
        public SumHandleRead(IAdsConnection connection, IDictionary <uint, Type> handleTypeDict, bool unicode = false, int strlen = 0x100) : base(connection, TwinCAT.Ads.SumCommand.SumCommand.SumAccessMode.ValueByHandle)
        {
            PrimitiveTypeConverter converter = PrimitiveTypeConverter.Default;

            if (unicode)
            {
                converter = PrimitiveTypeConverter.Unicode;
            }
            List <SumDataEntity> list = new List <SumDataEntity>();

            foreach (KeyValuePair <uint, Type> pair in handleTypeDict)
            {
                if (pair.Value == typeof(string))
                {
                    list.Add(new HandleSumReadAnyEntity(pair.Key, strlen, converter));
                    continue;
                }
                list.Add(new HandleSumReadAnyEntity(pair.Key, pair.Value, converter));
            }
            base.sumEntities = list;
        }
Exemplo n.º 26
0
        public static IObservable <NotificationEx> WhenNotificationEx(this IAdsConnection client, IDictionary <string, AnyTypeSpecifier> symbols, NotificationSettings settings, object userData)
        {
            if (symbols == null)
            {
                throw new ArgumentNullException("symbols");
            }
            if (symbols.Count == 0)
            {
                throw new ArgumentOutOfRangeException("Symbols list is empty!", "symbols");
            }
            IDisposableHandleBag bag = null;

            return(Observable.Select <EventPattern <AdsNotificationExEventArgs>, NotificationEx>(Observable.Where <EventPattern <AdsNotificationExEventArgs> >(Observable.FromEventPattern <AdsNotificationExEventHandler, AdsNotificationExEventArgs>(delegate(AdsNotificationExEventHandler h) {
                client.AdsNotificationEx += h;
                bag = new DisposableNotificationExHandleBag(client, symbols, settings, userData);
            }, delegate(AdsNotificationExEventHandler h) {
                bag.Dispose();
                bag = null;
                client.AdsNotificationEx -= h;
            }), ev => bag.Contains((uint)ev.get_EventArgs().NotificationHandle)), ev => new NotificationEx(ev.get_EventArgs())));
        }
Exemplo n.º 27
0
 public DisposableHandleBag(IAdsConnection client, IList <string> symbolPaths) : this(client)
 {
     if (symbolPaths == null)
     {
         throw new ArgumentNullException("symbolPaths");
     }
     if (symbolPaths.Count == 0)
     {
         throw new ArgumentOutOfRangeException("symbolPaths");
     }
     if (new SumCreateHandles(this.connection, symbolPaths).TryCreateHandles(out this.handleDict) == AdsErrorCode.NoError)
     {
         this.validHandleDict = new Dictionary <string, uint>();
         foreach (SumHandleInstancePathEntry entry in this.handleDict)
         {
             if (entry.ErrorCode == AdsErrorCode.NoError)
             {
                 this.validHandleDict.Add(entry.InstancePath, entry.Handle);
             }
         }
     }
 }
Exemplo n.º 28
0
        protected SumCommand(IAdsConnection connection, IList <SumDataEntity> sumEntities, SumCommandMode accessMode, SumAccessMode readWriteMode)
        {
            this.ig          = AdsReservedIndexGroups.SumCommandRead;
            this.connection  = connection;
            this.sumEntities = sumEntities;
            this.mode        = readWriteMode;
            this.commandMode = accessMode;
            switch (accessMode)
            {
            case SumCommandMode.Read:
                this.ig = AdsReservedIndexGroups.SumCommandRead;
                return;

            case SumCommandMode.Write:
                this.ig = AdsReservedIndexGroups.SumCommandWrite;
                return;

            case SumCommandMode.ReadWrite:
                this.ig = AdsReservedIndexGroups.SumCommandReadWrite;
                return;
            }
        }
Exemplo n.º 29
0
        public SumVariableRead(IAdsConnection connection, IEnumerable <AdsReadVariable> variables)
            : base(connection, SumAccessMode.IndexGroupIndexOffset)
        {
            if (connection is null)
            {
                throw new ArgumentNullException(nameof(connection));
            }
            _variables = variables?.ToList() ?? throw new ArgumentNullException(nameof(variables));
            if (variables.Any(v => v == null))
            {
                throw new ArgumentException($"{nameof(variables)} must not contain null items.");
            }

            var entities = new List <SumDataEntity>();

            foreach (var variable in variables)
            {
                uint handle = CreateVariableHandle(variable);
                entities.Add(new Entity(handle, variable.Size, 0));
            }

            sumEntities = entities;
        }
Exemplo n.º 30
0
        public static IDisposable WriteValues <T>(this IAdsConnection connection, string instancePath, IObservable <T> valueSequence, Action <Exception> errorHandler)
        {
            string[]            symbolPaths = new string[] { instancePath };
            DisposableHandleBag bag         = new DisposableHandleBag(connection, symbolPaths);
            Action <T>          action      = delegate(T v) {
                try
                {
                    uint handle = 0;
                    if (!bag.TryGetHandle(instancePath, out handle))
                    {
                        throw new AdsException($"Handle for '{instancePath}' is not created!");
                    }
                    connection.WriteAny((int)handle, v);
                }
                catch (Exception exception)
                {
                    errorHandler(exception);
                }
            };

            return(ObservableExtensions.Subscribe <T>(valueSequence, action, delegate(Exception ex) {
                try
                {
                    if (errorHandler == null)
                    {
                        throw ex;
                    }
                    errorHandler(ex);
                }
                finally
                {
                    bag.Dispose();
                }
            }, delegate {
                bag.Dispose();
            }));
        }