Obecnie próbuję utworzyć moją aplikację przy użyciu niektórych metod Async. Wszystkie moje IO są wykonywane przez jawne implementacje interfejsu i jestem trochę zdezorientowany, jak sprawić, by operacje były asynchroniczne.
Jak widzę rzeczy mam dwie opcje w realizacji:
interface IIO
{
void DoOperation();
}
OPCJA 1: wykonaj niejawną implementację asynchroniczną i poczekaj na wynik w niejawnej implementacji.
class IOImplementation : IIO
{
async void DoOperation()
{
await Task.Factory.StartNew(() =>
{
//WRITING A FILE OR SOME SUCH THINGAMAGIG
});
}
#region IIO Members
void IIO.DoOperation()
{
DoOperation();
}
#endregion
}
OPCJA 2: wykonaj jawną implementację asynchroniczną i poczekaj na zadanie z niejawnej implementacji.
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Czy jedna z tych implementacji jest lepsza od drugiej, czy też jest inna droga, o której nie myślę?
źródło
async
)async Task IIO.DoOperationAsync()
. A to znaczy, skądawait
zwróconyTask
? Gdziekolwiek zadzwoniszDoOperationAsync()
.Task.Run()
, ten kod IO powinien być sam asynchroniczny i zrobiłbyśawait
to bezpośrednio. Npline = await streamReader.ReadLineAsync()
.Lepszym rozwiązaniem jest wprowadzenie innego interfejsu dla operacji asynchronicznych. Nowy interfejs musi dziedziczyć z oryginalnego interfejsu.
Przykład:
PS Przeprojektuj swoje operacje asynchroniczne, aby zwracały Task zamiast void, chyba że naprawdę musisz zwrócić void.
źródło
GetAwaiter().GetResult()
zamiastWait()
? W ten sposób nie musisz rozpakowywać an,AggregateException
aby pobrać wyjątek wewnętrzny.class Impl : IIO, IIOAsync
. Same IIO i IIOAsync są jednak różnymi umowami, dzięki czemu można uniknąć wciągania „starych umów” do nowszego kodu.var c = new Impl(); IIOAsync asAsync = c; IIO asSync = c
.