tipos tipo ser referencia metodos interfaces instanciar genéricos genericos genericas debe constructores colecciones clases c# azure azure-storage azure-table-storage

c# - tipo - metodos genericos java



Clase genérica para realizar consultas de masa paralela. ¿Realimentación? (2)

¿Ha considerado usar la Biblioteca de tareas paralelas?

http://msdn.microsoft.com/en-us/library/dd537609.aspx

No entiendo por qué, pero parece que no hay ningún mecanismo en la biblioteca del cliente para realizar muchas consultas en paralelo para Windows Azure Table Storage. Creé una clase de plantilla que se puede usar para ahorrar un tiempo considerable, y puedes usarla como quieras. Sin embargo, apreciaría si pudieras desglosarlo y dar tu opinión sobre cómo mejorar esta clase.

public class AsyncDataQuery<T> where T: new() { public AsyncDataQuery(bool preserve_order) { m_preserve_order = preserve_order; this.Queries = new List<CloudTableQuery<T>>(1000); } public void AddQuery(IQueryable<T> query) { var data_query = (DataServiceQuery<T>)query; var uri = data_query.RequestUri; // required this.Queries.Add(new CloudTableQuery<T>(data_query)); } /// <summary> /// Blocking but still optimized. /// </summary> public List<T> Execute() { this.BeginAsync(); return this.EndAsync(); } public void BeginAsync() { if (m_preserve_order == true) { this.Items = new List<T>(Queries.Count); for (var i = 0; i < Queries.Count; i++) { this.Items.Add(new T()); } } else { this.Items = new List<T>(Queries.Count * 2); } m_wait = new ManualResetEvent(false); for (var i = 0; i < Queries.Count; i++) { var query = Queries[i]; query.BeginExecuteSegmented(callback, i); } } public List<T> EndAsync() { m_wait.WaitOne(); m_wait.Dispose(); return this.Items; } private List<T> Items { get; set; } private List<CloudTableQuery<T>> Queries { get; set; } private bool m_preserve_order; private ManualResetEvent m_wait; private int m_completed = 0; private object m_lock = new object(); private void callback(IAsyncResult ar) { int i = (int)ar.AsyncState; CloudTableQuery<T> query = Queries[i]; var response = query.EndExecuteSegmented(ar); if (m_preserve_order == true) { // preserve ordering only supports one result per query lock (m_lock) { this.Items[i] = response.Results.Single(); } } else { // add any number of items lock (m_lock) { this.Items.AddRange(response.Results); } } if (response.HasMoreResults == true) { // more data to pull query.BeginExecuteSegmented(response.ContinuationToken, callback, i); return; } m_completed = Interlocked.Increment(ref m_completed); if (m_completed == Queries.Count) { m_wait.Set(); } } }


Supongo que llego tarde a la fiesta. Yo agregaría dos cosas:

  1. ManualResetEvent es IDisposable. Por lo tanto, debe asegurarse de que se elimine en algún lugar.
  2. Manejo de errores: si una de las consultas falla, probablemente fallará todo. Probablemente debería volver a intentar las solicitudes fallidas. Alternativamente, puede devolver los valores que obtuvo con alguna indicación de qué consultas fallaron, para que la persona que llama pueda volver a intentar las consultas.
  3. Tiempos de espera del lado del cliente - no hay ninguno. Esto no es un problema si el lado del servidor agota su tiempo de espera, pero si alguna vez falla (por ejemplo, problemas de red), el cliente se bloqueará para siempre.

Además, creo que este es en realidad un mejor enfoque que la Biblioteca de tareas paralelas. Probé el enfoque de Tarea por consulta antes de esto. El código en realidad era más incómodo y tendía a tener muchos hilos activos. Todavía no he probado exhaustivamente con su código, pero parece funcionar mejor a primera vista.

Actualizar

He puesto algo de trabajo en una reescritura más o menos del código anterior. Mi reescritura elimina todos los bloqueos, admite los tiempos de espera del cliente de las transacciones bloqueadas (es raro, pero sucede, y realmente puede arruinar tu día), y un poco de lógica de manejo de excepciones. Hay una solución completa con pruebas en Bitbucket . El código más relevante reside en un archivo , aunque requiere algunos ayudantes que se encuentran en otras partes del proyecto.