public void Run(RunDelegate d1, ExceptionDelegate d2) { if (!open || ActiveCount() >= maxSize) { throw new Exception("free pool thread count exceeded or pool closed"); } Thread t = new Thread( delegate() { try { d1(); } catch (Exception e) { d2(e); } finally { lock (group) { group.Remove(Thread.CurrentThread); } } }); lock (group) { group.Add(t, t); } t.Start(); }
internal static unsafe int Initialize(IntPtr managedFunctionsBuffer, IntPtr nativeFunctionsBuffer, IntPtr sharedFunctionsBuffer) { assembliesContextManager = new AssembliesContextManager(); assembliesContextManager.CreateAssembliesContext(); pluginLoaders = new Dictionary <int, PluginLoader>(); unchecked { int head = 0; IntPtr *managedFunctions = (IntPtr *)managedFunctionsBuffer; Invoke = GenerateOptimizedFunction <InvokeDelegate>(managedFunctions[head++]); Exception = GenerateOptimizedFunction <ExceptionDelegate>(managedFunctions[head++]); Log = GenerateOptimizedFunction <LogDelegate>(managedFunctions[head++]); } unchecked { int head = 0; IntPtr *nativeFunctions = (IntPtr *)nativeFunctionsBuffer; nativeFunctions[head++] = typeof(Core).GetMethod("ExecuteAssemblyFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("LoadAssemblyFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("UnloadAssemblies", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); } sharedFunctions = sharedFunctionsBuffer; return(0xF); }
internal static unsafe int Initialize(IntPtr functions, int checksum) { assembliesContextManager = new AssembliesContextManager(); assembliesContextManager.CreateAssembliesContext(); plugins = new Dictionary <int, Plugin>(); int position = 0; IntPtr *buffer = (IntPtr *)functions; unchecked { int head = 0; IntPtr *managedFunctions = (IntPtr *)buffer[position++]; Invoke = GenerateOptimizedFunction <InvokeDelegate>(managedFunctions[head++]); Exception = GenerateOptimizedFunction <ExceptionDelegate>(managedFunctions[head++]); Log = GenerateOptimizedFunction <LogDelegate>(managedFunctions[head++]); } unchecked { int head = 0; IntPtr *nativeFunctions = (IntPtr *)buffer[position++]; nativeFunctions[head++] = typeof(Core).GetMethod("ExecuteAssemblyFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("LoadAssemblyFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("UnloadAssemblies", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); } sharedFunctions = buffer[position++]; sharedChecksum = checksum; return(0xF); }
public PendingCall(uint callId, Registry.RegisteredCall call, ReturnDelegate onReturn, ExceptionDelegate onException, Timer interval) { CallId = callId; Call = call; OnReturn = onReturn; OnException = onException; Interval = interval; }
/// <summary>A thread worker function that processes items from the work queue</summary> private static void ProcessQueuedItems() { // Get the system/hardware thread index this thread is going to use. We hope that // the threads more or less start after each other, but there is no guarantee that // tasks will be handled by the CPU cores in the order the queue was filled with. // This could be added, though, by using a WaitHandle so the thread creator could // wait for each thread to take one entry out of the queue. int hardwareThreadIndex; lock (hardwareThreads) { hardwareThreadIndex = hardwareThreads.Dequeue(); } if (Environment.OSVersion.Platform == PlatformID.Win32NT) { // Prevent this managed thread from impersonating another system thread. // In .NET, managed threads can supposedly be moved to different system threads // and, more worryingly, even fibers. This should make sure we're sitting on // a normal system thread and stay with that thread during our lifetime. Thread.BeginThreadAffinity(); // Assign the ideal processor, but don't force it. It's not a good idea to // circumvent the thread scheduler of a desktop machine, so we try to play nice. uint threadId = Kernel32.GetCurrentThreadId(); ProcessThread thread = GetProcessThread((int)threadId); if (thread != null) { thread.IdealProcessor = hardwareThreadIndex; } } // Keep processing tasks indefinitely for (; ;) { UserWorkItem workItem = getNextWorkItem(); // Execute the work item we just picked up. Make sure to accurately // record how many callbacks are currently executing. try { Interlocked.Increment(ref inUseThreads); workItem.Callback(workItem.State); } catch (Exception exception) { // Make sure we don't throw here. ExceptionDelegate exceptionHandler = ExceptionHandler; if (exceptionHandler != null) { exceptionHandler(exception); } } finally { Interlocked.Decrement(ref inUseThreads); } } }
private static void InvokeOnException(Exception ex) { ExceptionDelegate handler = OnException; if (handler != null) { handler(ex); } }
public static void ShowErrorThreadSafe(Exception ex) { ExceptionDelegate o = ShowError; if (BaseFormManager.MainForm == null) { throw (ex); } BaseFormManager.MainForm.BeginInvoke(o, ex); }
public static extern void SWIGRegisterExceptionCallbacks_gv( ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate);
public static extern void SWIGRegisterExceptionCallbacks_tinyWRAP( ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, ExceptionDelegate invalidCastDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate);
public static extern void SWIGRegisterExceptionCallbacks_FiftyOne.Mobile.Detection.Provider.Interop.Pattern( ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, ExceptionDelegate invalidCastDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate);
/// <summary>Executes a method and asserts that the specified exception is thrown.</summary> /// <param name="exceptionType">The type of exception to expect.</param> /// <param name="method">The method to execute.</param> /// <returns>The thrown exception.</returns> public static Exception Throws(Type exceptionType, ExceptionDelegate method) { try { method.Invoke(); } catch (Exception ex) { Assert.AreEqual(exceptionType, ex.GetType()); return(ex); } Assert.Fail("Expected exception '" + exceptionType.FullName + "' wasn't thrown."); return(null); }
/// <summary> /// Executes a method and asserts that the specified exception is thrown. /// </summary> /// <typeparam name="T">The type of exception to expect.</typeparam> /// <param name="method">The method to execute.</param> /// <returns>The thrown exception.</returns> public static void InnerException <T>(ExceptionDelegate method) where T : Exception { try { method.Invoke(); } catch (Exception ex) { TypeAssert.AreEqual(typeof(T), ex.InnerException); return; } Assert.Fail("Expected exception '" + typeof(T).FullName + "' wasn't thrown."); }
/// <summary>Executes a method and asserts that the specified exception is thrown.</summary> /// <typeparam name="T">The type of exception to expect.</typeparam> /// <param name="method">The method to execute.</param> /// <returns>The thrown exception.</returns> public static void InnerException <T>(ExceptionDelegate method) where T : Exception { try { method.Invoke(); } catch (Exception ex) { Assert.IsNotNull(ex as T); return; } Assert.Fail("Expected exception '" + typeof(T).FullName + "' wasn't thrown."); }
public void Run(RunDelegate d1, ExceptionDelegate d2) { new Thread( new ThreadStart(delegate() { try { d1(); } catch (Exception e) { d2(e); } })).Start(); }
/// <summary> /// Send a call to the server /// </summary> /// <param name="type">The call type (must have been registered with Registry.RegisterClientCall)</param> /// <param name="data">The data pack to send</param> /// <param name="onReturn">The callback to be executed when the server answers this call</param> /// <param name="onException">The callback to be executed when the server answer this call with an exception (or the call timeouts or the connection closes)</param> /// <param name="timeout">The timeout (in ms), 0 means no timeout</param> public void SendCall(uint type, Data data, ReturnDelegate onReturn = null, ExceptionDelegate onException = null, int timeout = 60000) { // Validate the data if (!IsReady) { throw new InvalidOperationException("The connection has already been closed"); } Registry.RegisteredCall call = Registry.GetClientCall(type); if (call == null) { throw new ArgumentException("Invalid call type " + type); } if (data.Format != call.ArgsFormat.FormatString) { throw new ArgumentException("Invalid data type '" + data.Format + "' for call " + type); } // Create the meta-data byte[] binData = data.GetBytes(); byte[] binMeta = new Data().AddUint(type).AddUint(++LastSentId).GetBytes(); byte[] binLength = new Data().AddUint((ulong)(binData.Length + binMeta.Length)).GetBytes(); // Send the call Socket.Write(binLength); Socket.Write(binMeta); Socket.Write(binData); // Set timeout Timer interval = null; if (timeout != 0) { interval = new Timer(timeout); interval.AutoReset = false; interval.Elapsed += TimeoutCallback; interval.Start(); } // Save info about the sent call PendingCalls.AddLast(new PendingCall(LastSentId, call, onReturn, onException, interval)); }
internal static unsafe int Initialize(IntPtr functions, int checksum) { try { assembliesContextManager = new AssembliesContextManager(); assembliesContextManager.CreateAssembliesContext(); int position = 0; IntPtr *buffer = (IntPtr *)functions; unchecked { int head = 0; IntPtr *managedFunctions = (IntPtr *)buffer[position++]; Invoke = GenerateOptimizedFunction <InvokeDelegate>(managedFunctions[head++]); InvokeArgument = GenerateOptimizedFunction <InvokeArgumentDelegate>(managedFunctions[head++]); Exception = GenerateOptimizedFunction <ExceptionDelegate>(managedFunctions[head++]); Log = GenerateOptimizedFunction <LogDelegate>(managedFunctions[head++]); } unchecked { int head = 0; IntPtr *nativeFunctions = (IntPtr *)buffer[position++]; nativeFunctions[head++] = typeof(Core).GetMethod("ExecuteManagedFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("ExecuteManagedFunctionArgument", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("FindManagedFunction", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("LoadAssemblies", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); nativeFunctions[head++] = typeof(Core).GetMethod("UnloadAssemblies", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); } sharedFunctions = buffer[position++]; sharedChecksum = checksum; } catch (Exception exception) { Exception("Runtime initialization failed\r\n" + exception.ToString()); } return(0xF); }
/// <summary> /// Executes a method and asserts that the specified exception is thrown. /// </summary> /// <typeparam name="T">The type of exception to expect.</typeparam> /// <param name="method">The method to execute.</param> /// <returns>The thrown exception.</returns> public static T Throws <T>(ExceptionDelegate method) where T : Exception { try { method.Invoke(); } catch (TargetInvocationException ex) { Assert.That(ex.InnerException, Is.TypeOf(typeof(T))); } catch (T ex) { return(ex); } catch (Exception ex) { Assert.Fail("Expected exception '" + typeof(T).FullName + "' but got exception '" + ex.GetType() + "'."); return(null); } Assert.Fail("Expected exception '" + typeof(T).FullName + "' wasn't thrown."); return(null); }
/// <summary> /// Used in negative testing, to make sure a certain expected exception happens. /// Added because SetExpectedErrorTypeInStep exists in Testcase, from which model test cases /// do not derive from. /// </summary> /// <param name="exceptionType">The type of the exception.</param> /// <param name="exceptionDelegate">Delegate that is expected to throw the exception.</param> /// <returns>True if the exception was thrown, false if it wasn't.</returns> protected bool ExpectException(string exceptionType, ExceptionDelegate exceptionDelegate) { bool exceptionCaught = false; try { exceptionDelegate(); } catch (Exception e) { if (e.GetType().ToString() == exceptionType) { GlobalLog.LogStatus(exceptionType.ToString() + " caught as expected"); exceptionCaught = true; } } if (!exceptionCaught) { GlobalLog.LogStatus("Fail - " + exceptionType.ToString() + " not thrown"); return(false); } return(true); }
//异常委托测试 static void ExceptionTest() { ExceptionDelegate exceptionDelegate = ExcptionTest.Method1; exceptionDelegate += ExcptionTest.Method2; exceptionDelegate += ExcptionTest.Method1; exceptionDelegate += ExcptionTest.Method2; Delegate[] delegates = exceptionDelegate.GetInvocationList(); foreach (ExceptionDelegate item in delegates) { try { item(); } catch { Console.WriteLine("捕获异常"); } } Console.WriteLine("------------"); for (int i = 0; i < delegates.Length; i++) { try { (delegates[i] as ExceptionDelegate)(); } catch { Console.WriteLine("捕获异常"); } } }
/// <summary> /// Send a call to the server /// </summary> /// <param name="type">The call type (must have been registered with Registry.RegisterClientCall)</param> /// <param name="data">The data pack to send</param> /// <param name="onReturn">The callback to be executed when the server answers this call</param> /// <param name="onException">The callback to be executed when the server answer this call with an exception (or the call timeouts or the connection closes)</param> /// <param name="timeout">The timeout (in ms), 0 means no timeout</param> public void SendCall(uint type, Data data, ReturnDelegate onReturn = null, ExceptionDelegate onException = null, int timeout = 60000) { // Validate the data if (!IsReady) throw new InvalidOperationException("The connection has already been closed"); Registry.RegisteredCall call = Registry.GetClientCall(type); if (call == null) throw new ArgumentException("Invalid call type " + type); if (data.Format != call.ArgsFormat.FormatString) throw new ArgumentException("Invalid data type '" + data.Format + "' for call " + type); // Create the meta-data byte[] binData = data.GetBytes(); byte[] binMeta = new Data().AddUint(type).AddUint(++LastSentId).GetBytes(); byte[] binLength = new Data().AddUint((ulong)(binData.Length + binMeta.Length)).GetBytes(); // Send the call Socket.Write(binLength); Socket.Write(binMeta); Socket.Write(binData); // Set timeout Timer interval = null; if (timeout != 0) { interval = new Timer(timeout); interval.AutoReset = false; interval.Elapsed += TimeoutCallback; interval.Start(); } // Save info about the sent call PendingCalls.AddLast(new PendingCall(LastSentId, call, onReturn, onException, interval)); }
internal static unsafe IntPtr ManagedCommand(Command command) { if (command.type == CommandType.Execute) { try { Invoke(command.function, command.value); } catch (Exception exception) { Exception(exception.ToString()); } return(IntPtr.Zero); } if (command.type == CommandType.Find) { IntPtr function = IntPtr.Zero; try { string method = Marshal.PtrToStringAnsi(command.method); if (plugin != null && !plugin.userFunctions.TryGetValue(method.GetHashCode(StringComparison.Ordinal), out function) && command.optional != 1) { Log(LogLevel.Error, "Managed function was not found \"" + method + "\""); } } catch (Exception exception) { Exception(exception.ToString()); } return(function); } if (command.type == CommandType.Initialize) { try { assembliesContextManager = new AssembliesContextManager(); assembliesContextWeakReference = assembliesContextManager.CreateAssembliesContext(); int position = 0; IntPtr *buffer = command.buffer; unchecked { int head = 0; IntPtr *runtimeFunctions = (IntPtr *)buffer[position++]; Invoke = GenerateOptimizedFunction <InvokeDelegate>(runtimeFunctions[head++]); Exception = GenerateOptimizedFunction <ExceptionDelegate>(runtimeFunctions[head++]); Log = GenerateOptimizedFunction <LogDelegate>(runtimeFunctions[head++]); } sharedEvents = buffer[position++]; sharedFunctions = buffer[position++]; sharedChecksum = command.checksum; } catch (Exception exception) { Exception("Runtime initialization failed\r\n" + exception.ToString()); } return(new IntPtr(0xF)); } if (command.type == CommandType.LoadAssemblies) { try { const string frameworkName = "UnrealEngine.Framework"; string assemblyPath = Assembly.GetExecutingAssembly().Location; string managedFolder = assemblyPath.Substring(0, assemblyPath.IndexOf("Plugins", StringComparison.Ordinal)) + "Managed"; string[] folders = Directory.GetDirectories(managedFolder); Array.Resize(ref folders, folders.Length + 1); folders[folders.Length - 1] = managedFolder; foreach (string folder in folders) { IEnumerable <string> assemblies = Directory.EnumerateFiles(folder, "*.dll", SearchOption.AllDirectories); foreach (string assembly in assemblies) { AssemblyName name = null; try { name = AssemblyName.GetAssemblyName(assembly); } catch (BadImageFormatException) { continue; } if (name?.Name != frameworkName) { plugin = new Plugin(); plugin.loader = PluginLoader.CreateFromAssemblyFile(assembly, config => { config.DefaultContext = assembliesContextManager.assembliesContext; config.IsUnloadable = true; }); plugin.assembly = plugin.loader.LoadAssemblyFromPath(assembly); AssemblyName[] referencedAssemblies = plugin.assembly.GetReferencedAssemblies(); foreach (AssemblyName referencedAssembly in referencedAssemblies) { if (referencedAssembly.Name == frameworkName) { Assembly framework = plugin.loader.LoadAssembly(referencedAssembly); using (assembliesContextManager.assembliesContext.EnterContextualReflection()) { Type sharedClass = framework.GetType(frameworkName + ".Shared"); if ((int)sharedClass.GetField("checksum", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null) == sharedChecksum) { plugin.userFunctions = (Dictionary <int, IntPtr>)sharedClass.GetMethod("Load", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { sharedEvents, sharedFunctions, plugin.assembly }); Log(LogLevel.Display, "Framework loaded succesfuly for " + assembly); } else { Log(LogLevel.Fatal, "Framework loading failed, version is incompatible with the runtime, please, recompile the project with an updated version referenced in " + assembly); } } return(IntPtr.Zero); } } command.type = CommandType.UnloadAssemblies; goto UnloadAssemblies; } } } } catch (Exception exception) { Exception("Loading of assemblies failed\r\n" + exception.ToString()); } return(IntPtr.Zero); } UnloadAssemblies: if (command.type == CommandType.UnloadAssemblies) { try { plugin?.loader.Dispose(); plugin = null; assembliesContextManager.UnloadAssembliesContext(); assembliesContextManager = null; uint unloadAttempts = 0; while (assembliesContextWeakReference.IsAlive) { GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); unloadAttempts++; if (unloadAttempts == 5000) { Log(LogLevel.Warning, "Unloading of assemblies took more time than expected. Trying to unload assemblies to the next breakpoint..."); } else if (unloadAttempts == 10000) { Log(LogLevel.Error, "Unloading of assemblies was failed! This might be caused by running threads, strong GC handles, or by other sources that prevent cooperative unloading."); break; } } assembliesContextManager = new AssembliesContextManager(); assembliesContextWeakReference = assembliesContextManager.CreateAssembliesContext(); } catch (Exception exception) { Exception("Unloading of assemblies failed\r\n" + exception.ToString()); } return(IntPtr.Zero); } return(IntPtr.Zero); }
public FlowBuilder() { flows = new List <ActionResultDelegate>(); errorHandler = (e) => { Console.WriteLine("Holy Cow !"); }; completeHandler = (flowId, data) => { Console.WriteLine("Complete !"); }; }
///<summary>Add an exception handler to be alerted of unhandled exceptions in the work delegate.</summary> public void AddExceptionHandler(ExceptionDelegate exceptionHandler) { _exceptionHandler+=exceptionHandler; }
/// <summary> /// Add specific <see cref="ExceptionDelegage"/> to collection /// </summary> /// <param name="exceptionDelegage"><see cref="ExceptionDelegage"/></param> internal void Add(ExceptionDelegate exceptionDelegage) { _exceptionDelegages = _exceptionDelegages ?? new List <ExceptionDelegate>(); _exceptionDelegages.Add(exceptionDelegage); }
internal static extern ErrorCode RegisterExceptionCallBack(IntPtr handle, ExceptionDelegate exceptionDelegate, IntPtr pUser);
public MyTodo(RunDelegate d1, ExceptionDelegate d2) { this.d1 = d1; this.d2 = d2; }
/// <summary> /// Creates new instance of <see cref="HandleExceptionHolder"/> class. /// </summary> /// <param name="exceptionDelegate"><see cref="ExceptionDelegate"/></param> internal HandleExceptionHolder(ExceptionDelegate exceptionDelegate) { this.Exceptions = new List <ExceptionDelegate>(); this.Exceptions.Add(exceptionDelegate); }
/// <summary> /// Creates new instance of the <see cref="HandleBuilder"/> class. /// </summary> /// <param name="exceptionDelegate"><see cref="ExceptionDelegate"/></param> public HandleBuilder(ExceptionDelegate exceptionDelegate) { this.ExceptionDelegateCollection = new ExceptionDelegateCollection(); this.ExceptionDelegateCollection.Add(exceptionDelegate); }
public void UnRegisterAll() { _ConnectCloseEvent = null; _ConnectFailedEvent = null; _TimeOutEvent = null; _SuccessEvent = null; _onProcess = null; _OthersErrorEvent = null; }
///<summary>Spread the given actions over the given numThreads. Blocks until threads have completed or timeout is reached. ///If numThreads is not provided then numThreads will default to Environment.ProcessorCount. This is typically what you should let happen. ///If onException is provided then one and only one onException event will be raised when any number of exceptions occur. ///All actions will run to completion regardless if any/all throw unhandled exceptions. ///If the timeout is reached, all threads will be killed and their corresponding actions will not complete. This can leave data in an ///undefined state, for example, if an action times out before instantiating an object, the object will be null. ///Throws exception on main thread if any action throws and unhandled exception and no onException was provided.</summary> public static void RunParallel(List<Action> listActions,TimeSpan timeout,int numThreads=0,ExceptionDelegate onException=null) { RunParallel(listActions,(int)timeout.TotalMilliseconds,numThreads,onException); }
///<summary>Spread the given actions over the given numThreads. Blocks until threads have completed or timeout is reached. ///If numThreads is not provided then numThreads will default to Environment.ProcessorCount. This is typically what you should let happen. ///If onException is provided then one and only one onException event will be raised when any number of exceptions occur. ///All actions will run to completion regardless if any/all throw unhandled exceptions. ///If the timeout is reached, all threads will be killed and their corresponding actions will not complete. This can leave data in an ///undefined state, for example, if an action times out before instantiating an object, the object will be null. ///Throws exception on main thread if any action throws and unhandled exception and no onException was provided.</summary> public static void RunParallel(List<Action> listActions,int timeoutMS=Timeout.Infinite,int numThreads=0,ExceptionDelegate onException=null, bool doRunOnCurrentThreadIf1Processor=false) { //Use as many threads as required by default. int threadCount=numThreads; if(threadCount<=0) { //No requirement on thread count was given so use the number of processor cores. threadCount=Environment.ProcessorCount; //Using at least 8 has neglibile negative impact so if the user didn't otherwise specify, use at least 8 threads. if(threadCount<8) { threadCount=8; } } Exception exceptionFirst=null; void HandleException() { if(exceptionFirst!=null) { //One of the actions threw an unhandled exception. if(onException==null) { //No handler was provided so throw. ExceptionDispatchInfo exInfo=ExceptionDispatchInfo.Capture(exceptionFirst); exInfo.Throw(); } //Caller wants to know about this exception so tell them. onException(exceptionFirst); } } if(threadCount==1 && doRunOnCurrentThreadIf1Processor) { foreach(Action action in listActions) { try { action(); } catch(Exception ex) { exceptionFirst=exceptionFirst??ex;//First exception in will get thrown. } } HandleException(); return; } //Make a group of threads to spread out the workload. List<Action> listActionsCur=new List<Action>(); int actionsPerThread=(int)Math.Ceiling((double)listActions.Count/threadCount); object locker=new object(); //No one outside of this method cares about this group name. They have no authority over this group. int threadID=1; string threadGroupGUID=Guid.NewGuid().ToString(); string threadGroupName="ODThread.ThreadPool()"+threadGroupGUID; for(int i = 0;i<listActions.Count;i++) { //Add to the current thread pool. listActionsCur.Add(listActions[i]); //If this thread pool is full then start it. if(listActionsCur.Count==actionsPerThread||i==(listActions.Count-1)) { ODThread odThread=new ODThread(new WorkerDelegate((ODThread o) => { ((List<Action>)o.Tag).ForEach(x => x()); })); odThread.Tag=new List<Action>(listActionsCur); odThread.Name=threadGroupName+"-"+threadID; odThread.GroupName=threadGroupName; odThread.AddExceptionHandler(new ExceptionDelegate((Exception e) => { lock (locker) { if(exceptionFirst==null) { //First in wins. exceptionFirst=e; } } })); //We just started a new thread pool so start a new one. listActionsCur.Clear(); odThread.Start(true); threadID++; } } //Wait for all appointment drawing threads to finish. JoinThreadsByGroupName(timeoutMS,threadGroupName,true); //We are back on the thread that called us now. HandleException(); }
private static void AcceptBegin(TcpListener tcpListener, AutoResetEvent evAccept, AcceptEndDelegate dlgtAcceptEnd, ExceptionDelegate dlgtException, int socketReceiveTimeoutInSec, int socketSendTimeoutInSec, int socketReceiveBufferSize, int socketSendBufferSize) { tcpListener.BeginAcceptSocket(new AsyncCallback(ar => { evAccept.Set(); lock (typeof(TcpChannel)) { try { dlgtAcceptEnd(new EasyTcpServer((ar.AsyncState as TcpListener).EndAcceptSocket(ar), onServerNotifies, socketReceiveTimeoutInSec, socketSendTimeoutInSec, socketReceiveBufferSize, socketSendBufferSize)); } catch (Exception e) { dlgtException(e); } } }), tcpListener); }
public FlowBuilder OnError(ExceptionDelegate error) { errorHandler = error; return(this); }