Получение имени метода задачи
Я ищу, чтобы получить имя метода / действия из задачи в C#. В частности, я реализую пользовательский планировщик задач и хотел бы генерировать статистику о продолжительности выполнения задачи, которую я затем агрегирую методом, запущенным внутри задачи. В отладчике visual studio вы можете получить к нему доступ и увидеть закрытую переменную m_action, а также аннотацию отображения отладчика, отображающую ее как Method={0}. Есть ли способ получить доступ к этому из самой задачи?
3 ответа:
Ну, вы можете использовать отражение, чтобы добраться до частного поля
m_action
, заданного переменнойTask
task
:var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic); Delegate action = fieldInfo.GetValue(task) as Delegate;
Затем получаем
Name
метода иDeclaringType
:var name = action.Method.Name; var type = action.Method.DeclaringType.FullName;
, чтобы получить полностью квалифицированный метод (
Но, как только задача выполняется до завершения,type + "." + name
)...m_action
являетсяnull
. Я не уверен, как это будет применяться с TaskFactory.Начать заново...
Вы можете наследовать от задачи, чтобы сделать это очень легко... Я просто собираюсь реализовать первый конструктор здесь для примера:
public class NamedTask : Task { public string MethodName { get; set; } public NamedTask(Action action) : base(action) { MethodName = action.Method.Name; } public NamedTask(Action action, CancellationToken cancellationToken) : base(action, cancellationToken) {} public NamedTask(Action action, TaskCreationOptions creationOptions) : base(action, creationOptions) {} public NamedTask(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base(action, cancellationToken, creationOptions) {} public NamedTask(Action<object> action, object state) : base(action, state) {} public NamedTask(Action<object> action, object state, CancellationToken cancellationToken) : base(action, state, cancellationToken) {} public NamedTask(Action<object> action, object state, TaskCreationOptions creationOptions) : base(action, state, creationOptions) {} public NamedTask(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base(action, state, cancellationToken, creationOptions) {} }
После этого...
NamedTask task = new NamedTask(() => AsyncMethod(arg1, arg2, argN)); string methodName = task.MethodName; // there's the name!
Еще примеры. Наследовать от
Task<T>
:public class NamedTask<T> : Task<T> { public string MethodName { get; set; } public NamedTask(Func<T> function) : base(function) { MethodName = function.Method.Name; } public NamedTask(Func<T> function, string methodName) : base(function) { MethodName = methodName; } ... }
Обрабатывать анонимные методы:
NamedTask<bool> task2 = new NamedTask<bool>(() => { // some arbitrary code return true; }); NamedTask<bool> task3 = new NamedTask<bool>(() => { // some arbitrary code return true; }, "ReturnTrueMethod"); string methodName2 = task2.MethodName; // returns "<LongRunning_Async>b__19" string methodName3 = task3.MethodName; // returns "ReturnTrueMethod"