smartthreadpool: suport callback delegates with no return value (WaitCallBack), use it on our fireandforget (other places later)

This commit is contained in:
UbitUmarov
2020-12-31 13:04:44 +00:00
parent 960a0fa360
commit b61df051db
4 changed files with 143 additions and 63 deletions

View File

@@ -54,7 +54,8 @@ namespace Amib.Threading.Internal
/// <summary>
/// Callback delegate for the callback.
/// </summary>
private readonly WorkItemCallback _callback;
private WorkItemCallback _callback;
private WaitCallback _callbackNoResult;
/// <summary>
/// State with which to call the callback delegate.
@@ -196,11 +197,7 @@ namespace Amib.Threading.Internal
///
/// We assume that the WorkItem object is created within the thread
/// that meant to run the callback
public WorkItem(
IWorkItemsGroup workItemsGroup,
WorkItemInfo workItemInfo,
WorkItemCallback callback,
object state)
public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
{
_workItemsGroup = workItemsGroup;
_workItemInfo = workItemInfo;
@@ -208,13 +205,34 @@ namespace Amib.Threading.Internal
if (_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed())
{
ExecutionContext ec = ExecutionContext.Capture();
if(ec != null)
_callerContext = ec.CreateCopy();
if (ec != null)
_callerContext = ec.CreateCopy();
ec.Dispose();
ec = null;
}
_callback = callback;
_callbackNoResult = null;
_state = state;
_workItemResult = new WorkItemResult(this);
Initialize();
}
public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WaitCallback callback, object state)
{
_workItemsGroup = workItemsGroup;
_workItemInfo = workItemInfo;
if (_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed())
{
ExecutionContext ec = ExecutionContext.Capture();
if (ec != null)
_callerContext = ec.CreateCopy();
ec.Dispose();
ec = null;
}
_callbackNoResult = callback;
_state = state;
_workItemResult = new WorkItemResult(this);
Initialize();
@@ -358,16 +376,33 @@ namespace Amib.Threading.Internal
{
try
{
if(_callerContext == null)
result = _callback(_state);
if(_callbackNoResult == null)
{
if(_callerContext == null)
result = _callback(_state);
else
{
ContextCallback _ccb = new ContextCallback( o =>
{
result =_callback(o);
});
ExecutionContext.Run(_callerContext, _ccb, _state);
}
}
else
{
ContextCallback _ccb = new ContextCallback( o =>
if (_callerContext == null)
_callbackNoResult(_state);
else
{
result =_callback(o);
});
ContextCallback _ccb = new ContextCallback(o =>
{
_callbackNoResult(o);
});
ExecutionContext.Run(_callerContext, _ccb, _state);
ExecutionContext.Run(_callerContext, _ccb, _state);
}
}
}
catch (Exception e)
@@ -977,6 +1012,8 @@ namespace Amib.Threading.Internal
_state = null;
}
}
_callback = null;
_callbackNoResult = null;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
@@ -6,6 +7,44 @@ namespace Amib.Threading.Internal
public class WorkItemFactory
{
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo,
WaitCallback callback, object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
WorkItem workItem = new WorkItem(
workItemsGroup,
new WorkItemInfo(workItemInfo),
callback,
state);
return workItem;
}
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WaitCallback callback, object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback,
CallToPostExecute = wigStartInfo.CallToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects,
WorkItemPriority = wigStartInfo.WorkItemPriority
};
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
@@ -13,10 +52,7 @@ namespace Amib.Threading.Internal
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback)
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemCallback callback)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
}
@@ -29,11 +65,8 @@ namespace Amib.Threading.Internal
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
WorkItemPriority workItemPriority)
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemCallback callback, WorkItemPriority workItemPriority)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
}
@@ -46,11 +79,8 @@ namespace Amib.Threading.Internal
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback)
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo, WorkItemCallback callback)
{
return CreateWorkItem(
workItemsGroup,
@@ -70,20 +100,19 @@ namespace Amib.Threading.Internal
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state)
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemCallback callback, object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
WorkItemInfo workItemInfo = new WorkItemInfo()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback,
CallToPostExecute = wigStartInfo.CallToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects,
WorkItemPriority = wigStartInfo.WorkItemPriority
};
WorkItem workItem = new WorkItem(
workItemsGroup,
@@ -140,12 +169,8 @@ namespace Amib.Threading.Internal
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback,
object state)
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo,
WorkItemCallback callback, object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);

View File

@@ -87,6 +87,35 @@ namespace Amib.Threading.Internal
#region QueueWorkItem
public IWorkItemResult QueueWorkItem(WaitCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, null);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WaitCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, null);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback, object state)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
@@ -187,9 +216,7 @@ namespace Amib.Threading.Internal
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
PreQueueWorkItem();
@@ -210,10 +237,7 @@ namespace Amib.Threading.Internal
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback,
WorkItemPriority workItemPriority)
{
PreQueueWorkItem();
@@ -234,11 +258,8 @@ namespace Amib.Threading.Internal
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute)
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
@@ -259,11 +280,8 @@ namespace Amib.Threading.Internal
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute,
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute,
WorkItemPriority workItemPriority)
{
PreQueueWorkItem();