【发布时间】:2021-12-15 02:40:14
【问题描述】:
有些代码我无法更改:
protected virtual void Method1() { }
private void Method2() { /* ... */ }
public void Method3()
{
Method1();
Method2();
}
当调用Method3() 时,我必须调用一个方法,在Method1 的覆盖中返回一个Task。但是,在那次通话之后,我需要知道 Method2 是否已被调用。
protected override async void Method1()
{
await MyOtherMethodAsync();
bool method2HasBeenCalledYet = ??
if (method2HasBeenCalledYet)
{
// ...
}
else
{
// ...
}
}
问题是,这取决于MyOtherMethodAsync 是否实际上是异步的(例如Task.Run())或不是(例如Task.CompletedTask)。
我有一个想法,每次我测试它都有效,但我不知道是否存在不起作用的情况(编辑:有)或者是否还有更多优雅的解决方案(编辑:显然有)。
protected override async void Method1()
{
bool method2HasBeenCalledYet = await IsAsync(MyOtherMethodAsync);
if (method2HasBeenCalledYet)
{
// ...
}
else
{
// ...
}
}
private async Task<bool> IsAsync(Func<Task> asyncAction)
{
int beforeThreadId = Thread.CurrentThread.ManagedThreadId;
await asyncAction().ConfigureAwait(false);
int afterThreadId = Thread.CurrentThread.ManagedThreadId;
return beforeThreadId != afterThreadId;
}
--
编辑用@Crowcoder和@Servy给出的解决方案:
protected override async void Method1()
{
var task = MyOtherMethodAsync();
if (!task.IsCompleted)
{
await task;
// ...
}
else
{
// ...
}
}
【问题讨论】:
-
你不能依靠线程 id 来告诉你。你可能会得到一个不同的线程,你可能不会。任务确实有
IsCompleted和Status,您可以使用它们。 -
@Crowcoder:我绝对是 100% 愚蠢的。只看 IsCompleted 显然是要走的路。
标签: c# asynchronous async-await task