我有一个简单的任务队列,它允许一次执行一个任务:
public class TaskQueue
{
public SemaphoreSlim semaphore;
public TaskQueue()
{
semaphore = new SemaphoreSlim(1);
}
public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
{
await semaphore.WaitAsync();
try
{
return await taskGenerator();
}
finally
{
semaphore.Release();
}
}
public async Task Enqueue(Func<Task> taskGenerator)
{
await semaphore.WaitAsync();
try
{
await taskGenerator();
}
finally
{
semaphore.Release();
}
}
}
我会像这样在其中排队任务:
private async Task SaveData()
{
//some code
await taskQueue.Enqueue(async () => { printed = await pm.Print(Template); });
//some code
}
现在我想做的是在Enqueue
方法内,添加一个包含信息$Print was called with parameter {Template}
的日志。 如何获取执行的方法的名称及其参数?
我知道我可以[CallerMemberName] string caller = ""
来获取有关在SaveData
内部进行的呼叫的信息,但是是否有属性或东西可以记录我想要的信息?
答案 0 :(得分:3)
这是可能(表达式树等),但是难以置信效率低下;也许更好的方法是改为使一个对象入队,即
abstract class ThingToDo {
public abstract Task DoTheThingAsync();
}
,将您的队列设置为ThingToDo
而不是Func<Task<T>>
的队列,那么您可以看到以下内容:
sealed class PrintThing : ThingToDo {
private readonly int x;
private readonly string y;
private readonly string caller;
public PrintThing(int x, string y, [CallerMemberName] string caller = null) {
this.x = x;
this.y = y;
this.caller = caller;
}
public override Task DoTheThingAsync() {...}
public override ToString() => $"{nameof(PrintThing)}, x={x}, y={y} from {caller}";
}
现在您可以轻松地输出任务。
实际上,这与编译器为带有捕获变量的lambda /匿名方法生成的 没什么不同。
答案 1 :(得分:0)
我会将日志添加到不同的方法中。这样,您还可以专门化每种方法生成的日志消息。