CancellationToken için varsayılan parametre


100

A eklemek istediğim bazı eşzamansız kodum var CancellationToken. Bununla birlikte, buna ihtiyaç duyulmayan birçok uygulama var, bu yüzden varsayılan bir parametreye sahip olmak istiyorum - belki CancellationToken.None. Ancak,

Task<x> DoStuff(...., CancellationToken ct = null)

verim

'System.Threading.CancellationToken' türüne yönelik standart bir dönüşüm olmadığından '' türündeki bir değer varsayılan parametre olarak kullanılamaz

ve

Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None)

'Ct' için varsayılan parametre değeri bir derleme zamanı sabiti olmalıdır

İçin varsayılan bir değere sahip olmanın herhangi bir yolu var CancellationTokenmı?

Yanıtlar:


157

Aşağıdakilerin işe yaradığı ortaya çıktı:

Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken))

...veya:

Task<x> DoStuff(...., CancellationToken ct = default) // C# 7.1 and later

bu, belgelerine göre , aynı şekilde yorumlanır CancellationToken.None:

default(CancellationToken)Boş bir iptal belirteci oluşturmak için C # ifadesini de kullanabilirsiniz .


4
Bu tam olarak ne çerçeve şu anda yok içten ama olur değil benim kodda bunu. Microsoft, uygulamalarını değiştirir ve CancellationToken.Nonebundan fazlası haline gelirse kodunuza ne olacağını düşünün default(CancellationToken).
noseratio

11
@Noseratio Bu, geriye dönük uyumluluğu büyük bir şekilde bozar, bu yüzden bunun olmasını beklemem. Ve başka ne default(CancellationToken)yapardı?
svick

4
@Noseratio: Çok katı davranıyorsun. Şanslar CancellationToken.Nonefiilen kullanımdan kaldırılacaktır. default(CancellationToken)Bunun yerine Microsoft bile kullanıyor . Örneğin , Entity Framework kaynak kodundan bu arama sonuçlarına bakın .
drowa

21
MSDN CancellationToken.None Özelliğinden : "Boş bir iptal belirteci oluşturmak için C # varsayılan (CancellationToken) ifadesini de kullanabilirsiniz" . C # 'ın gelecekteki bir sürümü bunu varsayılan parametre olarak kabul edene kadar hiçbiri bir hatadır.
MuiBienCarlota

5
Burada aynı İki eksik ara kombinasyonu telafi etmek için geliştiriciler, cancellationToken parametresi için None veya varsayılan CancellationToken ve ilerleme parametresi için null değerini iletebilir.
Arek Bal

25

CancellationToken için varsayılan bir değere sahip olmanın herhangi bir yolu var mı?

Ne yazık ki, CancellationToken.Noneisteğe bağlı bağımsız değişkenlerdeki varsayılan değerler için bir gereklilik olan derleme zamanı sabiti olmadığı için bu mümkün değildir.

Bununla birlikte, varsayılan parametreleri kullanmaya çalışmak yerine aşırı yüklenmiş bir yöntem yaparak aynı etkiyi sağlayabilirsiniz:

Task<x> DoStuff(...., CancellationToken ct)
{
    //...
}

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}

6
MSDN'deki Görev Tabanlı Eşzamansız Model belgelerinde (özellikle Sağlanacak Aşırı Yükleri Seçme bölümünde) açıklandığı gibi, bunu halletmek için önerilen yol budur .
Sam Harwell

CancellationToken.None == varsayılan doğru
eoleary

6
Sorun ne CancellationToken cancellationToken = default(CancellationToken)? Burada ayrıca açıklanmıştır blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/…
Ray

21

İşte azalan genel iyilik sırasına göre birkaç çözüm:

1. default(CancellationToken)Varsayılan değer olarak kullanma :

Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }

Anlamsal olarak, CancellationToken.Nonevarsayılan için ideal aday olacaktır, ancak bu şekilde kullanılamaz çünkü bir derleme zamanı sabiti değildir. default(CancellationToken)bundan sonraki en iyi şey, çünkü bir derleme zamanı sabiti ve eşdeğer olduğu resmi olarak belgelenmişCancellationToken.None .

2. CancellationTokenParametre olmadan yöntem aşırı yüklemesi sağlamak :

Veya isteğe bağlı parametrelere göre yöntem aşırı yüklemelerini tercih ederseniz ( buna ve bu konudaki bu soruya bakın ):

Task DoAsync(CancellationToken ct) { … } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token

Arayüz yöntemleri için, aynı şey, genişletme yöntemleri kullanılarak elde edilebilir:

interface IFoo
{
    Task DoAsync(CancellationToken ct);
}

static class Foo
{
    public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}

Bu, daha ince bir arayüzle sonuçlanır ve uygulayıcıları, yönlendirme yöntemi aşırı yüklemesini açıkça yazmaktan kurtarır.

3. Parametreyi null yapılabilir yapma ve nullvarsayılan değer olarak kullanma :

Task DoAsync(…, CancellationToken? ct = null)
{
    … ct ?? CancellationToken.None …
}

Bu çözümü en azından seviyorum çünkü null yapılabilir türler küçük bir çalışma zamanı ek yükü ile geliyor ve iptal belirtecine yapılan başvurular boş birleştirme operatörü nedeniyle daha ayrıntılı hale geliyor ??.


11

Diğer bir seçenek de bir Nullable<CancellationToken>parametre kullanmak , varsayılan olarak kullanmak nullve yöntem içinde onunla ilgilenmektir:

Task<x> DoStuff(...., CancellationToken? ct = null) {
    var token = ct ?? CancellationToken.None;
    ...
}

parlak! açık ara en iyi cevap bu
John Henckel

7

Daha yeni C # sürümleri, varsayılan (CancellationToken) sürüm için basitleştirilmiş bir sözdizimi sağlar. Örneğin:

Task<x> DoStuff(...., CancellationToken ct = default)

-1

Tofutim'in cevabı bir yol ama yorumlardan insanların bununla ilgili sorunları olduğunu görüyorum.

Bu durumda, birinin aşağıdaki gibi bir yönteme sahip olabileceğini önerdim:

Task<x> DoStuff(...., CancellationToken ct)
{
} 

ve şu şekilde aşırı yükleyin:

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}

Bu derlenir, çünkü CancellationToken.Nonederleme zamanında değerine gerek yoktur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.