Question

Je me demandais s'il y avait des implications de performance entre l'utilisation de TPL TaskFactory.FromAsync et en utilisant TaskFactory.StartNew Sur bloquer les versions des méthodes. J'écris un serveur TCP qui ne prendra pas plus de 100 connexions simultanées. Après avoir écrit du code avec la première option et le chainage de plusieurs opérations de lecture et d'écriture avec continuer, je me suis retrouvé avec du code laid et difficile à déboguer.

Je crois que l'écriture de code avec la version synchrone, puis l'emballer avec une tâche diminuerait la complexité et augmenterait la testabilité, mais je m'inquiète des implications de performances de cela.

Par exemple, y a-t-il des différences de performances entre ces 2 appels:

NetworkStream stream;
byte[] data;
int bytesRead;

//using FromAsync
Task<int> readChunk = Task<int>.Factory.FromAsync (
      stream.BeginRead, stream.EndRead,
      data, bytesRead, data.Length - bytesRead, null);

//using StartNew with blocking version
Task<int> readChunk2 = Task<int>.Factory.StartNew(() => 
      stream.Read(data, bytesRead, data.Length - bytesRead));
Était-ce utile?

La solution

Tu Tout à fait veux utiliser FromAsync Lorsqu'une API propose une version débutxxx / endxxx d'une méthode. La différence est que, dans le cas de quelque chose comme Stream ou Socket ou WebRequest, vous finirez par utiliser des E / S asynchrones sous les couvertures (par exemple, les ports d'achèvement d'E / S sur Windows), ce qui est beaucoup plus efficace que de bloquer plusieurs threads CPU faisant une opération synchrone. Ces méthodes fournissent le meilleur moyen d'atteindre l'évolutivité des E / S.

Consultez cette section du SDK .NET sur MSDN intitulé TPL et programmation asynchrone .net traditionnelle Pour plus d'informations sur la façon de combiner ces deux modèles de programmation pour atteindre le nirvana asynchrone.

Autres conseils

Suivre une copie à partir d'un lien externe:

Oui. Dans .NET 4, la bibliothèque parallèle de la tâche comprend un wrapper intégré pour le modèle APM (début / fin): tâche.factory.fromasync. Par exemple, si vous vouliez créer une tâche pour un appel à la méthode BeginRead / Endread de Stream, vous pourriez faire:

Stream s = ...;
byte [] buffer = ...;
Task<int> numBytesRead = Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);
// or with await
int numBytesRead = await Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);

Sous les couvertures, FromAsync est juste construit au-dessus de TaskPletionsource. Une version simple de Fromasync pour cet exemple de lecture ressemblerait à quelque chose comme:

var tcs = new TaskCompletionSource<TResult>();
s.BeginRead(buffer, 0, buffer.Length, iar =>
{
    try { tcs.SetResult(s.EndRead(iar)); }
    catch(Exception exc) { tcs.SetException(exc); }
}, null);
Task<int> numBytesRead = tcs.Task;

http://social.msdn.microsoft.com/forums/en/async/thread/ed8a14e8-d19a-42d1-bc3f-7017bdfed09c

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top