我有一个要求,我需要知道类的名称(ApiController),它有一个方法(GetMethod),由另一个类(OtherClass)的另一个方法(OtherMethod)调用.
为了帮助解释这一点,我希望下面的伪代码片段有所帮助.
public class ApiController
{
public void GetMethod()
{
OtherMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
public class OtherClass()
{
public void OtherMethod()
{
Console.WriteLine(/*I want to get the value 'ApiController' to print out*/)
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的:
[CallerMemberName]并使用StackTrace属性,但这些没有得到方法的类名我一直在关注asyncc#5.0中新功能的新公告.我对继续传递样式以及新的c#编译器对Eric Lippert的帖子中的代码片段所做的转换有基本的了解:
async void ArchiveDocuments(List<Url> urls)
{
Task archive = null;
for(int i = 0; i < urls.Count; ++i)
{
var document = await FetchAsync(urls[i]);
if (archive != null)
await archive;
archive = ArchiveAsync(document);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有些语言通过call-with-current-continuation(callcc)本地实现continuation ,但我真的不明白它是如何工作的或它究竟是做什么的.
所以这就是问题:如果安德斯等人.已经决定咬紧牙关,只是callcc在c#5.0而不是async/ await特殊情况下实现,上面的代码片段会是什么样子?
这是我发现在某些情况下很难调试等待任务中的死锁的一个简化示例:
class Program
{
static void Main(string[] args)
{
var task = Hang();
task.Wait();
}
static async Task Hang()
{
var tcs = new TaskCompletionSource<object>();
// do some more stuff. e.g. another await Task.FromResult(0);
await tcs.Task;
tcs.SetResult(0);
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子很容易理解为什么它会死锁,它正在等待稍后完成的任务。这看起来很愚蠢,但在更复杂的生产代码中可能会发生类似的情况,并且由于缺乏多线程经验可能会错误地引入死锁。
这个例子的有趣之处在于Hang方法内部没有像Task.Wait()or那样的线程阻塞代码Task.Result。然后当我附加 VS 调试器时,它只显示主线程正在等待任务完成。但是,没有线程显示代码在Hang使用并行堆栈视图的方法内部停止的位置。
这是我在并行堆栈中的每个线程上的调用堆栈(总共 3 个):
头1:
[Managed to Native Transition]
Microsoft.VisualStudio.HostingProcess.HostProc.WaitForThreadExit
Microsoft.VisualStudio.HostingProcess.HostProc.RunParkingWindowThread
System.Threading.ThreadHelper.ThreadStart_Context
System.Threading.ExecutionContext.RunInternal
System.Threading.ExecutionContext.Run
System.Threading.ExecutionContext.Run
System.Threading.ThreadHelper.ThreadStart
Run Code Online (Sandbox Code Playgroud)
主题 2:
[Managed to Native Transition]
Microsoft.Win32.SystemEvents.WindowThreadProc
System.Threading.ThreadHelper.ThreadStart_Context
System.Threading.ExecutionContext.RunInternal
System.Threading.ExecutionContext.Run
System.Threading.ExecutionContext.Run
System.Threading.ThreadHelper.ThreadStart …Run Code Online (Sandbox Code Playgroud) 可以说我有3节课:
class A {
void do_A() {
//Check object call hierarchy
}
}
class B {
void do_B() {
A a;
a.do_A();
}
}
class C {
void do_C() {
B b;
b.do_A();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我打电话给:
C c;
c.do_C();
Run Code Online (Sandbox Code Playgroud)
如何从A的do_A()中获取对象调用层次结构?
我的意思是我希望在a.do_A()中获得对象的引用(可以很容易地实现this),对象b的引用调用a.do_A(),以及对象c的引用调用b.do_B().
我认为这应该是可能的,因为我可以通过调用堆栈获得调用层次结构,所以我确信我应该能够获得有关调用这些方法的对象的更多信息.
c# ×4
async-await ×2
asynchronous ×1
callcc ×1
debugging ×1
function ×1
methods ×1
object ×1
stack-trace ×1