gpt4 book ai didi

c# - 等待抽象的异步任务

转载 作者:太空宇宙 更新时间:2023-11-03 17:39:10 26 4
gpt4 key购买 nike

我对 async/await 很陌生用法。我试图抽象异步和 await有条件地在 UI 中。我有一个抽象基类:

public abstract class Base
{
public abstract bool IsRunning { get; }
public abstract Task<bool> Run();
}

并从中衍生出一些实例,第一个是同步的:
internal class Derived1 : Base
{
private readonly Base baseCase;
private Task<bool> task;
public Derived1(Base baseCase)
{
this.baseCase = baseCase;
}
public override bool IsRunning
{
get { return false; }
}
public override Task<bool> Run()
{
task = new Task<bool>(() =>
{
bool ok = DoSomething();
return ok;
});
return task;
}
}

以及用于异步实现的派生类:
internal class Derived2 : Base
{
private readonly Base baseCase;
private Task<bool> task;
public Derived2(Base baseCase)
{
this.baseCase = baseCase;
}
public override bool IsRunning
{
get { return task != null && task.Status == TaskStatus.Running; }
}
public override Task<bool> Run()
{
task = new Task<bool>(() =>
{
bool ok = DoSomething();
return ok;
});
return task;
}
}

然后在UI中,我想 awaitasynchronous任务(如果用户在运行时配置中指定),如下所示:
internal class CaseMenuHandler
{
private async void OnRun(object sender, EventArgs args)
{
foreach (var case in Cases)
{
Base baseCaseRunner = GetCaseRunner(case);
try
{
bool ok = true;
if( something_holds ) {
ok = await baseCaseRunner.Run();
}
else {
ok = baseCaseRunner.Run().Result;
}
}
catch (Exception e)
{
LogError(...);
}
}
}

希望这很清楚。我可以执行上述操作,特别是在 if 块内有条件地等待吗?理想情况下,我想制作 Base类(class)只返回 bool而不是 Task<bool>Run方法,并且只有 Derived2类覆盖以返回 Task<bool> ,但我不清楚如何做到这一点。也许我应该返回 task.ResultRun Derived2的方法?如果有更好的方法,包括抽象或任何​​其他更正,请告诉我。欣赏任何想法。

编辑 #1
Run Derived1中同步实现的方法形式已在以下回复中阐明。我不允许更改 DoSomething 的签名方法虽然如此,鉴于此,我的 Run Derived2 中的方法(异步实现)现在看起来如下(感谢@Stripling 的评论):
    public override async Task<bool> Run()
{
task = new Task<bool>(() =>
{
bool ok = DoSomething();
return ok;
});
task.Start();
return await task;
}

编辑 #2 :

当我尝试上述操作时(也尝试在 task.Start() 定义之后放置一个 task 调用,我收到以下错误:
Cross-thread operation not valid: Application accessed domain object from a thread other than a legal thread.

最佳答案

Can I do the above, specifically awaiting conditionally inside an if block?



你可以,但你不应该这样做。如果你做对了,以阻塞方式专门调用同步任务并没有太大的优势:作为一般规则,你可以只 await返回的任务,如果它代表一个同步任务,那么 await将以很少的开销同步解决。

当我说“如果你做对了”时,这是正确的方法:
// synchronous
public override Task<bool> Run()
{
var result = DoSomething();
return Task.FromResult(result);
}


// asynchronous
public override async Task<bool> Run()
{
var result = await DoSomethingAsync();
return result;
}
await上面第一个例子的结果不会做任何线程切换或类似的事情。 await第二个可能的结果,取决于 DoSomethingAsync() 的实现.没有特别需要抽象层:您可以随时查看 Task是否完成,以及 await一个已经完成的任务总是会立即返回一个值。

关于c# - 等待抽象的异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37816774/

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