mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-07-30 17:30:40 +00:00
ASP.Net
This commit is contained in:
@@ -22,6 +22,7 @@ SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using Esiur.Misc;
|
||||
using Esiur.Resource;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -217,7 +218,17 @@ public class AsyncReply
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Trigger(object result)
|
||||
public void Trigger(object result) => TrySetResult(result, dispatchCallbacksAsynchronously: false);
|
||||
|
||||
/// <summary>
|
||||
/// Completes the reply immediately while dispatching callbacks independently.
|
||||
/// This is reserved for teardown paths where consumer code must not hold a
|
||||
/// transport or other infrastructure resource open.
|
||||
/// </summary>
|
||||
internal void TriggerDetached(object result) =>
|
||||
TrySetResult(result, dispatchCallbacksAsynchronously: true);
|
||||
|
||||
private bool TrySetResult(object result, bool dispatchCallbacksAsynchronously)
|
||||
{
|
||||
Action<object> singleCallback = null;
|
||||
Action<object>[] registeredCallbacks = null;
|
||||
@@ -227,7 +238,7 @@ public class AsyncReply
|
||||
lock (asyncLock)
|
||||
{
|
||||
if (exception != null || resultReady)
|
||||
return;
|
||||
return false;
|
||||
|
||||
ReadyTime = DateTime.Now;
|
||||
this.result = result;
|
||||
@@ -250,11 +261,24 @@ public class AsyncReply
|
||||
|
||||
waiter?.Set();
|
||||
|
||||
if (callbackCount == 1)
|
||||
if (dispatchCallbacksAsynchronously)
|
||||
{
|
||||
if (callbackCount == 1)
|
||||
QueueDetachedCallbacks(singleCallback, null, result);
|
||||
else if (registeredCallbacks != null)
|
||||
QueueDetachedCallbacks(null, registeredCallbacks, result);
|
||||
}
|
||||
else if (callbackCount == 1)
|
||||
{
|
||||
singleCallback(result);
|
||||
}
|
||||
else if (registeredCallbacks != null)
|
||||
{
|
||||
foreach (var callback in registeredCallbacks)
|
||||
callback(result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void TriggerError(Exception exception)
|
||||
@@ -262,6 +286,19 @@ public class AsyncReply
|
||||
TrySetException(exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Faults the reply immediately while dispatching callbacks independently.
|
||||
/// This is reserved for teardown paths where consumer code must not hold a
|
||||
/// transport or other infrastructure resource open.
|
||||
/// </summary>
|
||||
internal void TriggerErrorDetached(Exception exception)
|
||||
{
|
||||
TrySetException(
|
||||
exception,
|
||||
preserveSourceForAwait: false,
|
||||
dispatchCallbacksAsynchronously: true);
|
||||
}
|
||||
|
||||
internal void TriggerErrorFromBuilder(Exception exception, bool preserveSourceForAwait)
|
||||
{
|
||||
TrySetException(exception, preserveSourceForAwait);
|
||||
@@ -347,7 +384,10 @@ public class AsyncReply
|
||||
}
|
||||
}
|
||||
|
||||
private bool TrySetException(Exception sourceException, bool preserveSourceForAwait = false)
|
||||
private bool TrySetException(
|
||||
Exception sourceException,
|
||||
bool preserveSourceForAwait = false,
|
||||
bool dispatchCallbacksAsynchronously = false)
|
||||
{
|
||||
AsyncException asyncException;
|
||||
Action<AsyncException> singleCallback = null;
|
||||
@@ -378,12 +418,52 @@ public class AsyncReply
|
||||
|
||||
waiter?.Set();
|
||||
|
||||
if (callbackCount == 1)
|
||||
if (dispatchCallbacksAsynchronously)
|
||||
{
|
||||
if (callbackCount == 1)
|
||||
QueueDetachedCallbacks(singleCallback, null, asyncException);
|
||||
else if (registeredCallbacks != null)
|
||||
QueueDetachedCallbacks(null, registeredCallbacks, asyncException);
|
||||
}
|
||||
else if (callbackCount == 1)
|
||||
{
|
||||
singleCallback(asyncException);
|
||||
}
|
||||
else if (registeredCallbacks != null)
|
||||
{
|
||||
foreach (var callback in registeredCallbacks)
|
||||
callback(asyncException);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void QueueDetachedCallbacks<T>(
|
||||
Action<T> singleCallback,
|
||||
Action<T>[] registeredCallbacks,
|
||||
T value)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (singleCallback != null)
|
||||
{
|
||||
singleCallback(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var callback in registeredCallbacks)
|
||||
{
|
||||
try { callback(value); }
|
||||
catch (Exception exception) { Global.Log(exception); }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Global.Log(exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user