W poniższym kodzie, ze względu na interfejs, klasa LazyBar
musi zwrócić zadanie ze swojej metody (i ze względu na argumenty nie można go zmienić). Jeśli LazyBar
implementacja jest niezwykła, ponieważ zdarza się, że działa szybko i synchronicznie - jaki jest najlepszy sposób na zwrócenie zadania braku operacji z metody?
Przeszedłem Task.Delay(0)
poniżej, jednak chciałbym wiedzieć, czy ma to jakieś skutki uboczne wydajności, jeśli funkcja jest często wywoływana (na przykład argumenty, powiedzmy setki razy na sekundę):
- Czy ten cukier składniowy nie rozwija się w coś dużego?
- Czy zaczyna się zapychać pulę wątków mojej aplikacji?
- Czy tasak kompilatora jest wystarczający, aby radzić sobie
Delay(0)
inaczej? - Byłoby
return Task.Run(() => { });
inaczej?
Czy jest lepszy sposób?
using System.Threading.Tasks;
namespace MyAsyncTest
{
internal interface IFooFace
{
Task WillBeLongRunningAsyncInTheMajorityOfImplementations();
}
/// <summary>
/// An implementation, that unlike most cases, will not have a long-running
/// operation in 'WillBeLongRunningAsyncInTheMajorityOfImplementations'
/// </summary>
internal class LazyBar : IFooFace
{
#region IFooFace Members
public Task WillBeLongRunningAsyncInTheMajorityOfImplementations()
{
// First, do something really quick
var x = 1;
// Can't return 'null' here! Does 'Task.Delay(0)' have any performance considerations?
// Is it a real no-op, or if I call this a lot, will it adversely affect the
// underlying thread-pool? Better way?
return Task.Delay(0);
// Any different?
// return Task.Run(() => { });
// If my task returned something, I would do:
// return Task.FromResult<int>(12345);
}
#endregion
}
internal class Program
{
private static void Main(string[] args)
{
Test();
}
private static async void Test()
{
IFooFace foo = FactoryCreate();
await foo.WillBeLongRunningAsyncInTheMajorityOfImplementations();
return;
}
private static IFooFace FactoryCreate()
{
return new LazyBar();
}
}
}
Task.FromResult<object>(null)
.