我是一个对async/await
使用非常新手的人。我试图在UI中抽象出异步性和await
条件。我有一个抽象的基类:
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;
}
}
然后在用户界面中,如果用户在运行时配置中指定了,我希望能够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
类重写以返回Task<bool>
,但我不确定如何做到这一点。也许我应该在Derived2
的Run
方法中返回task.Result
?如果有更好的方式包括抽象或任何其他更正,请告诉我。感谢任何想法。编辑#1
下面的响应已经阐明了同步实现中
Derived1
的Run
方法形式。尽管如此,我不能更改DoSomething
方法的签名,因此鉴于此,我的Derived2
(异步实现)中的Run
方法现在如下所示(感谢@Stripling的评论): public override async Task<bool> Run()
{
task = new Task<bool>(() =>
{
bool ok = DoSomething();
return ok;
});
task.Start();
return await task;
}
编辑 #2:
当我尝试上述方法(也尝试在task
定义之后加入task.Start()
调用),我会得到以下错误提示:
Cross-thread operation not valid: Application accessed domain object from a thread other than a legal thread.
return await Task.Run(() => DoSomething());
。但是,如果DoSomething确实需要在单独的线程上运行,那么你的想法是正确的。 - StriplingWarrior