我期待從C#中的任務獲取方法/操作名稱。具體來說,我正在實現一個自定義任務調度程序,並且希望生成任務運行持續時間的統計信息,然後我將通過任務內運行的方法進行聚合。在visual studio調試器中,您可以訪問它並查看m_action私有變量以及調試器顯示註釋,並將其顯示爲Method = {0}。有沒有什麼辦法可以從任務本身訪問它?獲取任務的方法名稱
回答
嗯,你可以使用反射來獲取在私人m_action
領域,賦予了Task
變量task
:
var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
Delegate action = fieldInfo.GetValue(task) as Delegate;
然後獲得該方法的Name
和:
var name = action.Method.Name;
var type = action.Method.DeclaringType.FullName;
爲了得到完全限定的方法(type + "." + name
)...
但是,只要執行任務的完成,m_action
是null
。我不知道這將適用於TaskFactory.StartNew ...
- 嘗試反射以獲取m_action變量。
- 嘗試從
Envorinment.StackTrace
或從任務內部直接調用方法獲取信息。
您可以從任務繼承,使這個真正的輕鬆......我只是要在這裏實現第一個構造函數的例子:
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"
有趣的想法。除了:1.'MethodInfo.ToString()'不返回方法,名稱,它返回整個簽名。例如。像'Void AsyncMethod()'。要獲取名稱,請使用Name屬性。 2.正如Christian在評論中指出的那樣,這不會給lambdas帶來有用的結果。 – svick
好點。對於#1,如果您確實只需要方法名稱,則可以將其從簽名中解析出來。對於#2,在我的例子中,我使用了一個lambda ...所以我想也許你的意思是它不會給匿名方法有用嗎?在這種情況下,它仍將返回一個方法名稱 - 它只是編譯器爲匿名方法生成的方法名稱。在這裏,您可以創建另一個構造函數,允許您在創建任務時爲匿名方法指定自己的名稱。 – James
就像我說的,你可以使用'Name'屬性,不需要解析任何東西。 – svick
- 1. 通過任務定義標識獲取任務名稱的簡單方法
- 2. BCEL - 獲取類名稱,元素名稱和方法名稱
- 3. 從任務隊列中按名稱獲取任務
- 4. 任何獲取現有AVAsset資源名稱的方法?
- 5. 獲取調用方法的名稱javascript
- 6. 獲取方法的名稱使用WinDbg
- 7. 獲取當前方法的名稱
- 8. 獲取不同的Post方法名稱
- 9. 獲取GET方法變量的名稱
- 10. 在C#中獲取方法的名稱
- 11. 獲取包含的方法名稱
- 12. 獲取調用方法的名稱
- 13. 獲取路由名稱的HTTP方法
- 14. 獲取定義方法的名稱
- 15. 無法獲取SQL服務器名稱
- 16. 如何從VariableDeclarationStatement獲取方法名稱
- 17. 如何獲取調用方法名稱?
- 18. 如何獲取方法名稱?
- 19. 如何獲取父方法名稱?
- 20. 從動作獲取方法名稱
- 21. 如何獲取調用方法名稱?
- 22. 獲取服務器名稱
- 23. 封裝在一個輔助方法獲取方法的名稱
- 24. 在類和方法名稱中獲取行數的方法
- 25. 獲取靜態方法內的非靜態方法名稱
- 26. 如何獲取方法的名稱方法
- 27. 獲取創建WCF服務實例的調用方(或方法)的名稱?
- 28. 獲取gradle中任務的項目名稱
- 29. 如何從_ref獲取任務所有者的名稱?
- 30. 無法獲取DisplayAttribute名稱
問題是,這將是多麼有用。您(通常)傳遞給「Task」的lambda表達式由C#編譯器轉換爲方法,並獲取由編譯器生成的名稱。這些名稱不是[非常有說服力](http://stackoverflow.com/q/10450311/21567),並且很難將它們與實際代碼重新關聯。 –
@ Christian.K如果只限於非常簡單的lambda表達式,那麼可以使用'Expression'而不是委託並從中獲取方法名稱。 (當然,'Expression'可以調用幾種方法,所以你必須以某種方式選擇顯示哪一種,並且它也可能不會調用任何方法。) – svick