Eşzamansız yöntemler eklemek için bir kütüphaneyi değiştiriyorum. Should I expose synchronous wrappers for asynchronous methods?'dan, eşzamanlı yöntemi çağırırken Task.Result
etrafında bir sarıcı yazmamam gerektiğini bildiriyor. Ancak, her iki seçeneği de kitaplıkta tutmak istediğimizden, uyumsuzluk yöntemleri ve eşitleme yöntemleri arasında çok fazla kodun çoğaltılmasına neden gerek yok? Örneğin kitaplık şu anda TextReader.Read
yöntemini kullanır. Eşzamansız değişimin bir parçası olarak, TextReader.ReadAsync
yöntemini kullanmak istiyoruz. Bu, kütüphanelerin özünde bulunduğundan, eşzamanlı ve eşzamansız yöntemler arasında bir çok kodu çoğaltmam gerekecek gibi görünüyordu (kodu DRY'yi olabildiğince saklamak istiyoruz). Ya da, kodu karıştıran ve TPL'nin düzeltmeye çalıştığı izlenimi veren PreRead
ve PostRead
yöntemlerinde onları yeniden düzenlemem gerekiyor.Kütüphanelerde eşzamanlı ve eşzamansız yöntemler yazmak ve onu korumak için desen DRY
yöntemini yalnızca Task.Return()
'da kaydırma hakkında düşünüyorum. Bir görev olmakla birlikte, TPL'deki gelişmeler farklı bir iş parçacığına geçmemelidir ve ben hala normalde olduğu gibi kodun çoğunu beklemede olan async'i kullanabilirim. Daha sonra sadece Task.Result
veya Wait()
olmak için eşzamanlı bir sarıcı olması iyi olur mu?
.net kitaplığındaki diğer örneklere baktım. StreamReader
, async ve async olmayanlar arasındaki kodu çoğaltıyor gibi görünüyor. MemoryStream
, Task.FromResult
yapar.
Ayrıca heryerde planlama yapmak için sadece bir kütüphane olarak ConfigureAwait(false)
ekleyebilirim.
Güncelleme:
ben çoğaltılamaz kod bahsediyorum ne
public decimal ReadDecimal()
{
do
{
if (!Read())
{
SetInternalProperies()
}
else
{
return _reader.AsDecimal();
}
} while (_reader.hasValue)
}
public async Task<decimal> ReadDecimalAsync()
{
do
{
if (!await ReadAsync())
{
SetInternalProperies()
}
else
{
return _reader.AsDecimal();
}
} while (_reader.hasValue)
}
Bu küçük bir örnek ama sadece kod değişikliği bekleyen ve görev görebilirsiniz olduğunu.
Açıkça belirtmek gerekirse, kitaplıktaki her yerde async/bekletme ve TPL kullanarak kodlamak istiyorum ancak yine de eski eşitleme yöntemlerinin de çalışması gerekiyor. Ben sadece Task.FromResult()
eşitleme yöntemleri ile ilgili değilim. Ben eşitleme yöntemini istiyor ve kökünde de o zaman bir görev olarak senkron bir sarmalayıcı sahip olmak Tamam olur
public decimal ReadDecimal()
{
return ReadDecimalAsyncInternal(true).Result;
}
public async Task<decimal> ReadDecimal()
{
return await ReadDecimalAsyncInternal(false);
}
private async Task<decimal> ReadDecimalAsyncInternal(bool syncRequest)
{
do
{
if (!await ReadAsync(syncRequest))
{
SetInternalProperies()
}
else
{
return _reader.AsDecimal();
}
} while (_reader.hasValue)
}
private Task<bool> ReadAsync(bool syncRequest)
{
if(syncRequest)
{
return Task.FromResult(streamReader.Read())
}
else
{
return StreamReader.ReadAsync();
}
}
Senkronize ve zaman uyumsuz bir yöntem sürümünü neden göstermek istiyorsunuz? Bir işlem senkron veya asenkron olabilir. İkisi de olamaz. Doğru olanı seçin, ikisini de değil. Daha sonra müşteri kodu ile, o zaman arayabilirsin. –
Bu bir kütüphanedir. Bunu kullanan mevcut kodumuz var ve bunları değiştirmek zorunda kalmak istemiyoruz. Biz size pozitif bir şey verir – CharlesNRice
A Task.Result sarıcı Library.Method ve Library.MethodAsync gibi kütüphaneye "zaman uyumsuz" yöntemi ekliyoruz TextReader.Read ve TextReader.ReadAsync aynı şey. Bekleme, bu görevde depolanan değeri eşzamanlı olarak alacaktır. Yöntem imzası yanıltıcıdır. Yalnızca asenkron içsel olarak bulunan async yöntemlerini açığa çıkarın. – usr