zaman uyumsuz geri dönüş görevini bekliyor


131

Birisi bunun senkronize bir yöntemde ne anlama geldiğini açıklayabilir mi? Yöntemi değiştirmeye çalışırsam asynco zaman VS şikayet et.

Bu çalışıyor:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Bu çalışmıyor:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

Yani temelde bunun tam olarak ne anlama geldiğini bilmek istiyorum: Task.FromResult<object>(null);



@LB hmm işe yarıyor! Ama aynı zamanda return;çalışırsam da ...!
David Dury

2
"çalışmıyor", neyin çalışmadığına dair çok iyi bir açıklama sağlamaz. Aldığınız hata mesajı nedir?
John Koerner

@JohnKoerner Derleyicinin, bir voidişlevde bir değer döndürmeye çalıştığınız gibi size aynı hatayı verebileceğinin oldukça açık olduğunu düşünüyorum .
binki

Yanıtlar:


236

asyncyöntemler normal yöntemlerden farklıdır. asyncYöntemlerden ne iade ederseniz edin , bir Task.

Hiçbir değer (void) Taskdöndürmezseniz, sarılır , döndürürseniz intsarılır Task<int>vb.

Senin zaman uyumsuz yöntem dönmek gerekiyorsa intsiz yöntemin dönüş türü işaretlemek istiyorum Task<int>ve düz dönersiniz intdeğil Task<int>. Derleyici dönüştürecektir intiçin Task<int>sizin için.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

Sameway, Task<object>yönteminizin dönüş türü döndüğünüzdeTask<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

Yönteminiz geri Taskdöndüğü için herhangi bir değer döndürmemelidir. Aksi takdirde derlenmez.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

İfade içermeyen eşzamansız yöntemin olmadığını awaitunutmayın async.


1
Benim için bu dönüş türü çalışmıyor (sanırım yanlış bir şey yapıyorum). Örnek statik zaman uyumsuz Task <string> DoStuff () {... = await SomeMethodAsync (); "dize değeri" döndür; } .. var x = DoStuff (); Ama bu x - "Task <string>" tipinde, "string" tipinde değil ... Neden böyle?
Prokurors

3
@Prokurors Sizin DoStuff()de beklemeniz gerekiyor . Örneğin:var x = await DoStuff();
Sriram Sakthivel

5
Olmalıreturn await Task.FromResult<object>(null);
sandeep talabathula

@sandeeptalabathula sıfıra eşittir
Sriram Sakthivel

2
@ProfK Task.WhenAnybir örnektir.
2017

55

Zaman uyumsuz kullanırken await anahtar sözcüğünü kullanmanız gerekir ve işlev dönüş türünüz genel olmalıdır. İşte dönüş değeri olan bir örnek:

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

İşte dönüş değeri olmayan bir örnek:

public async Task MethodName()
{
    await Task.CompletedTask;
}

Bunları oku:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx ve Görevler: http://msdn.microsoft.com/en-us/library/system.threading .tasks (v = vs.110) .aspx

Zaman uyumsuz: http://msdn.microsoft.com/en-us/library/hh156513.aspx Bekleyin: http://msdn.microsoft.com/en-us/library/hh156528.aspx


9
nullSahte bir görev beklemek yerine doğrudan geri dönebilirsiniz .
Lee

5
@Lee, ancak bunu yaparsanız, derleyici, asyncyöntemin awaitanahtar kelimeyi yöntemde bir yerde kullanmak için bir öneri ile eşzamansız olarak çalışacağından şikayet eder (bir uyarı verir) . Derleyici uyarı sesini azaltmak için return Task.FromResult((object)null);yalnızca asyncanahtar kelimeyi kullanmanızı ve kaldırmanızı öneririm .
binki

Evet, sadece returnbir Görevde kullanmayı denedim , ancak görev yürütülmeye devam ediyor çünkü returnbirTask
Turner Bass

30

Eşzamansız anahtar sözcüğünü eklemek, bir durum makinesinin oluşturulmasını basitleştirmek için yalnızca sözdizimsel şekerdir. Özünde, derleyici kodunuzu alır;

public async Task MethodName()
{
     return null;
}

Ve onu şuna dönüştürür;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Kodunuzda herhangi bir awaitanahtar kelime varsa, derleyici yönteminizi almalı ve onu yürütmek için gerekli durum makinesini temsil edecek bir sınıfa dönüştürmelidir. Her bir awaitanahtar kelimede, değişkenlerin durumu ve yığın sınıfın alanlarında korunacak, sınıf kendisini beklediğiniz göreve bir tamamlama kancası olarak ekleyecek ve sonra geri dönecektir.

Bu görev tamamlandığında, göreviniz yeniden yürütülecektir. Dolayısıyla, değişkenlerin durumunu geri yüklemek ve kodunuzun bir sonraki katmanına atlamak için yöntemin üstüne fazladan bir kod eklenir.

Bkz zaman uyumsuz & beklediği, üretir? kanlı bir örnek için.

Bu işlemin, derleyicinin yineleyici yöntemlerini verim ifadeleriyle işleme biçimiyle birçok ortak noktası vardır.


2

Bu, String türünde bir Görev döndüren bir Görevdir (C # anonim işlev veya başka bir deyişle, bir temsilci 'Func' kullanılır)

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }

1
Yanıt olarak kodu gönderirken, lütfen gösterdiğiniz şeyle ilgili bazı açıklamalar ekleyin. Bu durumda, zaten birkaç cevabı olan eski bir soruya bir cevap ekliyorsunuz. Lütfen yeni cevabınızın neyi gösterdiğini açıklayan ve diğer cevaplarda gösterilmeyen bir veya iki cümle ekleyin. Cevabınızda yanlış bir şey olduğunu söylemiyorum, sadece kodunuzla gösterdiğiniz şeyi kelimelere dökerek başkalarına yardım etmenizi istiyorum.
ToolmakerSteve

0

Zaman uyumsuz yöntemlerden uygun yanıtlar almak için, bu görev yöntemlerini çağırırken beklemeniz gerekir. Bu, görev türü yerine döndürülen değer türüne geri dönüştürülmesini bekleyecektir.

Örneğin var content = await StringAsyncTask (

nerede genel zaman uyumsuz Task < String > StringAsyncTask ())

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.