squ*_*boo 1 c# task abstract async-await
我对这个async/await用法很新.我试图await在UI中抽象异步和条件.我有一个抽象的基类:
public abstract class Base
{
public abstract bool IsRunning { get; }
public abstract Task<bool> Run();
}
Run Code Online (Sandbox Code Playgroud)
从它一些派生的实例,第一个是同步的:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
和异步实现的派生类:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在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(...);
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这很清楚.我可以这样做,特别是在if块内有条件地等待吗?理想情况下,我想使Base类只返回bool,而不是Task<bool>为Run方法,而只显示Derived2类重写返回一个Task<bool>,但我不如何做到这一点清楚.也许我应该回归task.Result里面的Run方法Derived2?如果有更好的方法,包括抽象或任何其他更正,请告诉我.欣赏任何想法.
编辑#1
在下面的答复中阐明Run了同步实施的方法形式Derived1.我不能改变的签名DoSomething,虽然方法,所以鉴于此,我Run在方法Derived2(异步执行)如下所示现在(感谢@瘦长的评论):
public override async Task<bool> Run()
{
task = new Task<bool>(() =>
{
bool ok = DoSomething();
return ok;
});
task.Start();
return await task;
}
Run Code Online (Sandbox Code Playgroud)
编辑#2:
当我尝试上面的内容时(也尝试task.Start()在task定义后调用,我收到以下错误:
Cross-thread operation not valid: Application accessed domain object from a thread other than a legal thread.
Run Code Online (Sandbox Code Playgroud)
我可以这样做,特别是在if块内有条件地等待吗?
你可以,但你不应该这样做.如果你做得对,那么以阻塞方式专门调用同步任务没有什么大的优势:作为一般规则,你可以只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;
}
Run Code Online (Sandbox Code Playgroud)
await上面第一个例子的结果不会做任何线程切换或类似的事情.await取决于实施的第二种可能的结果DoSomethingAsync().还有的抽象层没有特别的需要:你总是可以检查Task到是否它完成与否,以及await荷兰国际集团已经完成的任务将总是立即返回一个值.
| 归档时间: |
|
| 查看次数: |
1944 次 |
| 最近记录: |