我对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,我想await
对asynchronous
任务(如果用户在运行时配置中指定的话),如下所示:
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
类仅返回bool
而不Task<bool>
为Run
方法返回,并且仅使Derived2
类重写以返回a Task<bool>
,但是我不清楚如何做到这一点。也许我应该返回task.Result
里面的Run
方法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.
我可以执行上述操作,特别是在if块中有条件地等待吗?
您可以,但不必这样做。如果您做对了,以阻塞的方式专门调用同步任务没有太大的优势:作为一般规则,您可以只await
返回返回的Task,如果它代表一个同步任务,则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()
。不需要特别的抽象层:您可以始终检查aTask
是否已完成,并且await
已经完成的任务总是会立即返回一个值。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句