gpt4 book ai didi

c# - 获取对任务状态机的实际 this 引用

转载 作者:行者123 更新时间:2023-11-30 17:34:33 24 4
gpt4 key购买 nike

我正在尝试篡改任务内部状态机的状态,但我无法找到在我的任务方法中实际访问状态机引用的方法。

class Test
{
async Task IndexAsync()
{
var nottheactualtype = GetType(); //This references the "Test" class, but this operation is actually located in the nested state machine class named "IndexAsync", in the method "MoveNext()".
var actualcalledmethod = new StackTrace().GetFrame(0).GetMethod(); //This shows the actual method currently being run: IndexAsync.MoveNext().
//But how do I get the reference to my current IndexAsync class?
}
}

如何获取当前正在运行的生成状态机的引用?

最佳答案

这很糟糕,而且不能保证有效(这取决于实现细节)——但这对我有用……它基本上会激发状态机将延续传递给等待者。然后我们可以从继续委托(delegate)的目标中获取状态机。

丑陋、丑陋、丑陋的代码……但它确实对我有用:)

using System;
using System.Reflection;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using static System.Reflection.BindingFlags;

public class StateMachineProvider
{
private static readonly StateMachineProvider instance = new StateMachineProvider();

public static StateMachineProvider GetStateMachine() => instance;

public StateMachineAwaiter GetAwaiter() => new StateMachineAwaiter();

public class StateMachineAwaiter : INotifyCompletion
{
private Action continuation;

public bool IsCompleted => continuation != null;

public void OnCompleted(Action continuation)
{
this.continuation = continuation;
// Fire the continuation in a separate task.
// (We shouldn't just call it synchronously.)
Task.Run(continuation);
}

public IAsyncStateMachine GetResult()
{
var target = continuation.Target;
var field = target.GetType()
.GetField("m_stateMachine", NonPublic | Instance);
return (IAsyncStateMachine) field.GetValue(target);
}
}
}

class Test
{
static void Main()
{
AsyncMethod().Wait();
}

static async Task AsyncMethod()
{
int x = 10;
IAsyncStateMachine machine = await StateMachineProvider.GetStateMachine();
Console.WriteLine($"x={x}"); // Force the use across an await boundary
Console.WriteLine($"State machine type: {machine.GetType()})");
Console.WriteLine("Fields:");
var fields = machine.GetType().GetFields(Public | NonPublic | Instance);
foreach (var field in fields)
{
Console.WriteLine($"{field.Name}: {field.GetValue(machine)}");
}
}
}

输出:

x=10
State machine type: Test+<AsyncMethod>d__1)
Fields:
<>1__state: -1
<>t__builder: System.Runtime.CompilerServices.AsyncTaskMethodBuilder
<x>5__1: 10
<machine>5__2: Test+<AsyncMethod>d__1
<>s__3:
<>s__4: System.Reflection.FieldInfo[]
<>s__5: 6
<field>5__6: System.Reflection.FieldInfo <field>5__6
<>u__1:

关于c# - 获取对任务状态机的实际 this 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42299642/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com