通过任务队列调用时获取方法名称和参数

我有一个简单的任务队列,它允许一次执行一个任务:

 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内部进行的呼叫的信息,但是是否有属性或东西可以记录我想要的信息?

T87182380 回答:通过任务队列调用时获取方法名称和参数

这是可能(表达式树等),但是难以置信效率低下;也许更好的方法是改为使一个对象入队,即

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 /匿名方法生成的 没什么不同。

,

我会将日志添加到不同的方法中。这样,您还可以专门化每种方法生成的日志消息。

本文链接:https://www.f2er.com/3111518.html

大家都在问