mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-06-28 04:35:14 +08:00
Button.AsyncClick
This commit is contained in:
parent
8decf9e554
commit
c439a46e38
2
AndroidTest/Resources/Resource.designer.cs
generated
2
AndroidTest/Resources/Resource.designer.cs
generated
@ -14,7 +14,7 @@ namespace AndroidTest
|
||||
{
|
||||
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.2.120")]
|
||||
public partial class Resource
|
||||
{
|
||||
|
||||
|
2
CPF.Android/Resources/Resource.designer.cs
generated
2
CPF.Android/Resources/Resource.designer.cs
generated
@ -14,7 +14,7 @@ namespace CPF.Android
|
||||
{
|
||||
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.2.120")]
|
||||
public partial class Resource
|
||||
{
|
||||
|
||||
|
@ -15,5 +15,7 @@
|
||||
<ProjectReference Include="..\CPF.Windows\CPF.Windows.csproj" />
|
||||
<ProjectReference Include="..\CPF\CPF.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -6,7 +6,6 @@ using CPF.Drawing;
|
||||
using CPF.Shapes;
|
||||
using CPF.Styling;
|
||||
using CPF.Svg;
|
||||
using CPF.Toolkit.Controls;
|
||||
using CPF.Toolkit.Dialogs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -21,13 +20,13 @@ namespace CPF.Toolkit.Demo
|
||||
{
|
||||
|
||||
}
|
||||
MainViewModel vm = new MainViewModel();
|
||||
protected override void InitializeComponent()
|
||||
{
|
||||
Title = "标题";
|
||||
Width = 500;
|
||||
Height = 400;
|
||||
Background = null;
|
||||
var vm = new MainViewModel();
|
||||
this.DataContext = this.CommandContext = vm;
|
||||
|
||||
Children.Add(new WindowFrame(this, new WrapPanel
|
||||
@ -71,13 +70,19 @@ namespace CPF.Toolkit.Demo
|
||||
Content = "loading",
|
||||
Commands = { { nameof(Button.Click),(s,e) => vm.LoadingTest() } }
|
||||
},
|
||||
new AsyncButton
|
||||
new Button
|
||||
{
|
||||
Content = "AsyncButton",
|
||||
Command = vm.AsyncClick,
|
||||
},
|
||||
}.Assign(out var asyncButton),
|
||||
}
|
||||
}));
|
||||
|
||||
asyncButton.AsyncClick += AsyncButton_AsyncClick;
|
||||
}
|
||||
|
||||
private async Task AsyncButton_AsyncClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await this.vm.AsyncClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using CPF.Controls;
|
||||
using CPF.Toolkit.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@ -49,10 +48,10 @@ namespace CPF.Toolkit.Demo
|
||||
//this.Dialog.Sucess(result);
|
||||
}
|
||||
|
||||
public IAsyncCommand AsyncClick => new AsyncCommand(async () =>
|
||||
public async Task AsyncClick()
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
await Task.Delay(3000);
|
||||
this.Dialog.Alert("test");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,5 +21,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CPF\CPF.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,31 +0,0 @@
|
||||
using CPF.Controls;
|
||||
using CPF.Toolkit.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Toolkit.Controls
|
||||
{
|
||||
public class AsyncButton : Button
|
||||
{
|
||||
|
||||
protected override void InitializeComponent()
|
||||
{
|
||||
base.InitializeComponent();
|
||||
this.Triggers.Add(nameof(IsEnabled), Relation.Me, null, (nameof(Background), "224,224,224"));
|
||||
}
|
||||
|
||||
public IAsyncCommand Command { get; set; }
|
||||
|
||||
protected override async void OnClick(RoutedEventArgs e)
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
base.OnClick(e);
|
||||
if (this.Command != null)
|
||||
{
|
||||
await this.Command.ExecuteAsync();
|
||||
}
|
||||
this.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Toolkit.Input
|
||||
{
|
||||
public class AsyncCommand : IAsyncCommand
|
||||
{
|
||||
public AsyncCommand(Func<Task> execute)
|
||||
{
|
||||
this.execute = execute;
|
||||
}
|
||||
|
||||
private readonly Func<Task> execute;
|
||||
private Task executionTask;
|
||||
|
||||
public Task ExecutionTask
|
||||
{
|
||||
get => this.executionTask;
|
||||
private set
|
||||
{
|
||||
if (ReferenceEquals(this.executionTask, value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.executionTask = value;
|
||||
bool isAlreadyCompletedOrNull = value?.IsCompleted ?? true;
|
||||
if (isAlreadyCompletedOrNull)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning => ExecutionTask is { IsCompleted: false };
|
||||
|
||||
|
||||
public Task ExecuteAsync()
|
||||
{
|
||||
Task executionTask = ExecutionTask;
|
||||
if (this.execute is not null)
|
||||
{
|
||||
executionTask = ExecutionTask = this.execute();
|
||||
}
|
||||
return executionTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Toolkit.Input
|
||||
{
|
||||
public interface IAsyncCommand
|
||||
{
|
||||
Task ExecutionTask { get; }
|
||||
bool IsRunning { get; }
|
||||
Task ExecuteAsync();
|
||||
}
|
||||
}
|
@ -38,6 +38,8 @@ namespace CPF.Controls
|
||||
overridePropertys.Override(nameof(Background), new UIPropertyMetadataAttribute((ViewFill)"221,221,221", UIPropertyOptions.AffectsRender));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata)
|
||||
//{
|
||||
// base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata);
|
||||
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using CPF.Input;
|
||||
using CPF.Drawing;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Controls
|
||||
{
|
||||
@ -20,7 +21,7 @@ namespace CPF.Controls
|
||||
}
|
||||
|
||||
bool isMouseLeftButtonPressed;
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
protected override async void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
if (!e.Handled)
|
||||
@ -72,6 +73,7 @@ namespace CPF.Controls
|
||||
try
|
||||
{
|
||||
OnClick();
|
||||
await OnAsyncClick();
|
||||
exceptionThrown = false;
|
||||
}
|
||||
finally
|
||||
@ -100,7 +102,7 @@ namespace CPF.Controls
|
||||
// e.Handled = true;
|
||||
// }
|
||||
//}
|
||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
||||
protected override async void OnMouseUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
if (e.MouseButton == MouseButton.Left)
|
||||
@ -128,6 +130,7 @@ namespace CPF.Controls
|
||||
if (l.X >= 0 && l.Y >= 0 && l.X <= r.Width && l.Y <= r.Height)
|
||||
{
|
||||
OnClick();
|
||||
await OnAsyncClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,7 +139,7 @@ namespace CPF.Controls
|
||||
}
|
||||
|
||||
bool IsSpaceKeyDown = false;
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
protected override async void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
if (ClickMode == ClickMode.Hover || e.Handled)
|
||||
@ -159,6 +162,7 @@ namespace CPF.Controls
|
||||
if (ClickMode == ClickMode.Press)
|
||||
{
|
||||
OnClick();
|
||||
await OnAsyncClick();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
@ -177,6 +181,7 @@ namespace CPF.Controls
|
||||
}
|
||||
|
||||
OnClick();
|
||||
await OnAsyncClick();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
@ -195,7 +200,7 @@ namespace CPF.Controls
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyEventArgs e)
|
||||
protected override async void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyUp(e);
|
||||
if (ClickMode == ClickMode.Hover || e.Handled)
|
||||
@ -222,7 +227,10 @@ namespace CPF.Controls
|
||||
}
|
||||
|
||||
if (shouldClick)
|
||||
{
|
||||
OnClick();
|
||||
await OnAsyncClick();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -250,22 +258,29 @@ namespace CPF.Controls
|
||||
IsPressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnClick()
|
||||
{
|
||||
//var p1 = PointToScreen(new Point());
|
||||
//var p4 = PointToScreen(new Point(ActualSize.Width, ActualSize.Height));
|
||||
//var rect = new Rect(p1, p4);
|
||||
//if (rect.Contains(Root.InputManager.MouseDevice.Location))
|
||||
//{
|
||||
OnClick(new RoutedEventArgs(this));
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnClick(RoutedEventArgs e)
|
||||
{
|
||||
RaiseEvent(e, nameof(Click));
|
||||
}
|
||||
|
||||
protected async Task OnAsyncClick()
|
||||
{
|
||||
await OnAsyncClick(new RoutedEventArgs(this));
|
||||
}
|
||||
|
||||
protected virtual async Task OnAsyncClick(RoutedEventArgs e)
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
await AsyncRaiseEvent(e, nameof(AsyncClick));
|
||||
this.IsEnabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置 Click 事件何时发生。
|
||||
/// </summary>
|
||||
@ -296,6 +311,12 @@ namespace CPF.Controls
|
||||
add { AddHandler(value); }
|
||||
remove { RemoveHandler(value); }
|
||||
}
|
||||
|
||||
public event AsyncEventHandler<RoutedEventArgs> AsyncClick
|
||||
{
|
||||
add { AddHandler(value); }
|
||||
remove { RemoveHandler(value); }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -13,6 +13,7 @@ using CPF.Animation;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF
|
||||
{
|
||||
@ -1708,10 +1709,6 @@ namespace CPF
|
||||
/// <param name="eventName"></param>
|
||||
public void RaiseEvent<TEventArgs>(in TEventArgs eventArgs, string eventName)
|
||||
{
|
||||
//if (eventArgs is RoutedEventArgs routed)
|
||||
//{
|
||||
// routed.Sender = this;
|
||||
//}
|
||||
OnRaiseEvent(eventArgs, eventName);
|
||||
|
||||
if (observers != null && eventArgs is EventArgs args)
|
||||
@ -1739,10 +1736,6 @@ namespace CPF
|
||||
v = item.Target.Target;
|
||||
objs.Add(v);
|
||||
}
|
||||
//else if (item.Relation != null && this is UIElement)
|
||||
//{
|
||||
// objs.AddRange(item.Relation.Query(this as UIElement));
|
||||
//}
|
||||
else
|
||||
{
|
||||
v = CommandContext;
|
||||
@ -1778,14 +1771,6 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
}
|
||||
//v.GetType().GetMethod(item.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).FastInvoke(v, ps);
|
||||
|
||||
//var m = obj.GetType().GetMethod(item.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
//if (m == null)
|
||||
//{
|
||||
// throw new Exception("未找到该方法 " + item.MethodName);
|
||||
//}
|
||||
//m.Invoke(obj, ps);
|
||||
obj.Invoke(item.MethodName, ps);
|
||||
}
|
||||
}
|
||||
@ -1804,6 +1789,88 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AsyncRaiseEvent<TEventArgs>(TEventArgs eventArgs, string eventName)
|
||||
{
|
||||
OnRaiseEvent(eventArgs, eventName);
|
||||
|
||||
if (observers != null && eventArgs is EventArgs args)
|
||||
{
|
||||
EventObserver<EventArgs, CpfObject> eventObserver = new EventObserver<EventArgs, CpfObject>(eventName, args, this);
|
||||
foreach (var observer in observers)
|
||||
{
|
||||
observer.OnNext(eventObserver);
|
||||
}
|
||||
}
|
||||
|
||||
if (commands != null)
|
||||
{
|
||||
List<Command> list;
|
||||
if (commands.commands.TryGetValue(eventName, out list))
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (item.Action == null)
|
||||
{
|
||||
var objs = new List<object>();
|
||||
object v = null;
|
||||
if (item.Target != null)
|
||||
{
|
||||
v = item.Target.Target;
|
||||
objs.Add(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
v = CommandContext;
|
||||
if (v != null)
|
||||
{
|
||||
objs.Add(v);
|
||||
}
|
||||
}
|
||||
foreach (var obj in objs)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
object[] ps = new object[item.Params == null ? 0 : item.Params.Length];
|
||||
if (item.Params != null && item.Params.Length > 0)
|
||||
{
|
||||
//ps = item.Params;
|
||||
item.Params.CopyTo(ps, 0);
|
||||
for (int i = 0; i < ps.Length; i++)
|
||||
{
|
||||
var p = ps[i];
|
||||
if (p is CommandParameter)
|
||||
{
|
||||
if ((CommandParameter)p == CommandParameter.EventArgs)
|
||||
{
|
||||
ps[i] = eventArgs;
|
||||
}
|
||||
else if ((CommandParameter)p == CommandParameter.EventSender)
|
||||
{
|
||||
ps[i] = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.Invoke(item.MethodName, ps);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Action(this, eventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var handler = Events[eventName];
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.AsyncInvoke(this, eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnRaiseEvent<TEventArgs>(in TEventArgs eventArgs, string eventName)
|
||||
{
|
||||
|
||||
|
9
CPF/Input/AsyncEventHandler.cs
Normal file
9
CPF/Input/AsyncEventHandler.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Input
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e);
|
||||
}
|
@ -6,6 +6,7 @@ using System.Reflection;
|
||||
using System.Linq.Expressions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection.Emit;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Reflection
|
||||
{
|
||||
@ -69,6 +70,7 @@ namespace CPF.Reflection
|
||||
}
|
||||
}
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, InvokeHandler>> methods = new ConcurrentDictionary<Type, ConcurrentDictionary<string, InvokeHandler>>();
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, AsyncInvokeHandler>> asyncMethods = new ConcurrentDictionary<Type, ConcurrentDictionary<string, AsyncInvokeHandler>>();
|
||||
static KeyValuePair<Type, ConcurrentDictionary<string, InvokeHandler>>[] saveMethods;
|
||||
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, SetHandler<object>>> setValues = new ConcurrentDictionary<Type, ConcurrentDictionary<string, SetHandler<object>>>();
|
||||
@ -106,6 +108,28 @@ namespace CPF.Reflection
|
||||
return fun(instance, parameters);
|
||||
}
|
||||
|
||||
public static async Task AsyncInvoke(this object instance, string methodName, params object[] parameters)
|
||||
{
|
||||
var type = instance.GetType();
|
||||
|
||||
if (!asyncMethods.TryGetValue(type, out var list))
|
||||
{
|
||||
list = new ConcurrentDictionary<string, AsyncInvokeHandler>();
|
||||
asyncMethods.TryAdd(type, list);
|
||||
}
|
||||
if (!list.TryGetValue(methodName, out var fun))
|
||||
{
|
||||
var minfo = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (minfo == null)
|
||||
{
|
||||
throw new Exception(type + "未找到方法:" + methodName);
|
||||
}
|
||||
fun = AsyncMethodCache.CreateInvokeDelegate(minfo);
|
||||
list.TryAdd(methodName, fun);
|
||||
}
|
||||
await fun(instance, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反射快速调用
|
||||
/// </summary>
|
||||
@ -115,10 +139,15 @@ namespace CPF.Reflection
|
||||
/// <returns></returns>
|
||||
public static object FastInvoke(this MethodInfo methodInfo, object instance, params object[] parameters)
|
||||
{
|
||||
//return FastReflectionCaches.MethodInvokerCache.Get(methodInfo).Invoke(instance, parameters);
|
||||
return methodCache.Get(methodInfo).Invoke(instance, parameters);
|
||||
}
|
||||
public static async Task FastAsyncInvoke(this MethodInfo methodInfo, object instance, params object[] parameters)
|
||||
{
|
||||
await asyncMethodCache.Get(methodInfo).Invoke(instance, parameters);
|
||||
}
|
||||
|
||||
static MethodCache methodCache = new MethodCache();
|
||||
static AsyncMethodCache asyncMethodCache = new AsyncMethodCache();
|
||||
|
||||
/// <summary>
|
||||
/// 快速动态设置对象的属性值
|
||||
@ -369,7 +398,57 @@ namespace CPF.Reflection
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncMethodCache : FastReflectionCache<MethodInfo, AsyncInvokeHandler>
|
||||
{
|
||||
protected override AsyncInvokeHandler Create(MethodInfo key)
|
||||
{
|
||||
return CreateInvokeDelegate(key);
|
||||
}
|
||||
|
||||
public static AsyncInvokeHandler CreateInvokeDelegate(MethodInfo methodInfo)
|
||||
{
|
||||
var instanceParameter = Expression.Parameter(typeof(object), "instance");
|
||||
var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
|
||||
|
||||
var parameterExpressions = new List<Expression>();
|
||||
var paramInfos = methodInfo.GetParameters();
|
||||
for (int i = 0; i < paramInfos.Length; i++)
|
||||
{
|
||||
BinaryExpression valueObj = Expression.ArrayIndex(
|
||||
parametersParameter, Expression.Constant(i));
|
||||
UnaryExpression valueCast = Expression.Convert(
|
||||
valueObj, paramInfos[i].ParameterType);
|
||||
|
||||
parameterExpressions.Add(valueCast);
|
||||
}
|
||||
|
||||
var instanceCast = methodInfo.IsStatic ? null :
|
||||
Expression.Convert(instanceParameter, methodInfo.ReflectedType);
|
||||
|
||||
var methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);
|
||||
|
||||
if (methodCall.Type == typeof(void))
|
||||
{
|
||||
var lambda = Expression.Lambda<Action<object, object[]>>(
|
||||
methodCall, instanceParameter, parametersParameter);
|
||||
|
||||
Action<object, object[]> execute = lambda.Compile();
|
||||
return (instance, parameters) =>
|
||||
{
|
||||
execute(instance, parameters);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var castMethodCall = Expression.Convert(methodCall, typeof(Task));
|
||||
var lambda = Expression.Lambda<AsyncInvokeHandler>(
|
||||
castMethodCall, instanceParameter, parametersParameter);
|
||||
|
||||
return lambda.Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
class MethodCache : FastReflectionCache<MethodInfo, InvokeHandler>
|
||||
{
|
||||
protected override InvokeHandler Create(MethodInfo key)
|
||||
@ -482,6 +561,8 @@ namespace CPF.Reflection
|
||||
//iLGenerator.Ret();
|
||||
//return (InvokeHandler)dynamicMethod.CreateDelegate(typeof(InvokeHandler));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class PropertyGetCache : FastReflectionCache<PropertyInfo, GetHandler<object>>
|
||||
@ -578,5 +659,6 @@ namespace CPF.Reflection
|
||||
public delegate void SetHandler<T>(object target, T value);
|
||||
public delegate T GetHandler<T>(object target);
|
||||
public delegate object InvokeHandler(object target, object[] paramters);
|
||||
public delegate Task AsyncInvokeHandler(object target, object[] paramters);
|
||||
public delegate void SetRefHandler<T, V>(ref T target, V value);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using CPF.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF
|
||||
{
|
||||
@ -48,6 +49,24 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AsyncInvoke(object sender, object e)
|
||||
{
|
||||
if (delegates != null)
|
||||
{
|
||||
foreach (var item in delegates.ToArray())
|
||||
{
|
||||
if (item.reference.TryGetTarget(out var target) || item.method.IsStatic)
|
||||
{
|
||||
await item.method.FastAsyncInvoke(target, sender, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
delegates.Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
delegates = null;
|
||||
|
Loading…
Reference in New Issue
Block a user