У мене є інтерфейс з деякими функціями асинхронізації.
Task
Я вважаю, що методи повертаються . async
є деталізацією реалізації, тому її не можна застосувати до методів інтерфейсу.
Деяким класам, що реалізує інтерфейс, чекати нічого не можна, а деякі можуть просто кинути.
У цих випадках ви можете скористатися тим фактом, що async
є деталізацією.
Якщо у вас немає нічого await
, тоді ви можете просто повернутися Task.FromResult
:
public Task<int> Success() // note: no "async"
{
... // non-awaiting code
int result = ...;
return Task.FromResult(result);
}
У випадку з кидком NotImplementedException
процедура дещо словніша:
public Task<int> Fail() // note: no "async"
{
var tcs = new TaskCompletionSource<int>();
tcs.SetException(new NotImplementedException());
return tcs.Task;
}
Якщо у вас є багато методів метання NotImplementedException
(що саме по собі може вказувати на те, що деякий рефакторинг на рівні дизайну був би хорошим), тоді ви можете перетворити складність у клас помічників:
public static class TaskConstants<TResult>
{
static TaskConstants()
{
var tcs = new TaskCompletionSource<TResult>();
tcs.SetException(new NotImplementedException());
NotImplemented = tcs.Task;
}
public static Task<TResult> NotImplemented { get; private set; }
}
public Task<int> Fail() // note: no "async"
{
return TaskConstants<int>.NotImplemented;
}
Клас хелперів також зменшує сміття, яке в іншому випадку GC повинен був би зібрати, оскільки кожен метод з тим самим типом повернення може поділяти його Task
та NotImplementedException
об'єкти.
У моїй бібліотеці AsyncEx у мене є кілька інших прикладів типу "константа завдань" .