【发布时间】:2016-06-15 21:54:33
【问题描述】:
我对@987654322@ 的用法非常陌生。我正在尝试在 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;
}
}
然后在 UI 中,我想在asynchronous 任务上执行await(如果用户在运行时配置中指定),如下所示:
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 的cmets):
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.
【问题讨论】:
-
您能用高层次的术语解释一下您要做什么吗?
-
@YacoubMassad:让我试试。我试图有一个抽象类和一个派生类异步实现一些方法,而另一个派生类没有,然后在 UI 中根据我所处的情况有条件地等待。
-
WRT 编辑 #2:您正在尝试对只希望由特定线程访问的对象执行某些操作。这种事情经常发生在具有指定 UI 线程的应用程序中。如果不知道是哪一行代码导致了错误,就很难确切知道如何为您提供帮助。
-
@StriplingWarrior:我正在尝试进一步调试,但到目前为止,Edit #1 中的用法看起来还可以吗?
标签: c# async-await task abstract