Я очень новичок в использовании async/await
. Я пытаюсь аннулировать асинхронность и 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>
, но я не знаю, как это сделать. Возможно, я должен вернуть 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;
}
EDIT # 2:
Когда я пытаюсь выше (также пытался ставить task.Start()
вызов после task
определения, я получаю следующее сообщение об ошибке:
Cross-thread operation not valid: Application accessed domain object from a thread other than a legal thread.
Можете ли вы объяснить, что вы пытаетесь сделать на условиях высокого уровня? –
@YacoubMassad: Позвольте мне попробовать. Я пытаюсь иметь абстрактный класс и один производный класс, который реализует некоторые методы асинхронно, в то время как другой производный класс не делает этого, а затем в пользовательском интерфейсе, чтобы условно ждать, в зависимости от того, в каком случае я вхожу. –
Взгляните на это: http://blog.stephencleary.com/2013/01/async-oop-1-inheritance-and-interfaces.html –