Si bien LINQ realmente no tiene esto en sí mismo, el marco en sí sí ... Puede ejecutar fácilmente su propio ejecutor de consultas asincrónicas en 30 líneas más o menos ... De hecho, acabo de lanzar esto para usted:)
EDITAR: Al escribir esto, he descubierto por qué no lo implementaron. No puede manejar tipos anónimos ya que tienen un alcance local. Por lo tanto, no tiene forma de definir su función de devolución de llamada. Esto es algo muy importante ya que muchas cosas de linq a sql las crean en la cláusula de selección. Cualquiera de las siguientes sugerencias sufre el mismo destino, ¡así que todavía creo que esta es la más fácil de usar!
EDITAR: La única solución es no utilizar tipos anónimos. Puede declarar la devolución de llamada simplemente tomando IEnumerable (sin args de tipo), y use reflection para acceder a los campos (ICK !!). Otra forma sería declarar la devolución de llamada como "dinámica" ... oh ... espera ... Aún no ha salido. :) Este es otro ejemplo decente de cómo se podría utilizar la dinámica. Algunos pueden llamarlo abuso.
tirar esto en la biblioteca de utilidades:
public static class AsynchronousQueryExecutor
{
public static void Call<T>(IEnumerable<T> query, Action<IEnumerable<T>> callback, Action<Exception> errorCallback)
{
Func<IEnumerable<T>, IEnumerable<T>> func =
new Func<IEnumerable<T>, IEnumerable<T>>(InnerEnumerate<T>);
IEnumerable<T> result = null;
IAsyncResult ar = func.BeginInvoke(
query,
new AsyncCallback(delegate(IAsyncResult arr)
{
try
{
result = ((Func<IEnumerable<T>, IEnumerable<T>>)((AsyncResult)arr).AsyncDelegate).EndInvoke(arr);
}
catch (Exception ex)
{
if (errorCallback != null)
{
errorCallback(ex);
}
return;
}
//errors from inside here are the callbacks problem
//I think it would be confusing to report them
callback(result);
}),
null);
}
private static IEnumerable<T> InnerEnumerate<T>(IEnumerable<T> query)
{
foreach (var item in query) //the method hangs here while the query executes
{
yield return item;
}
}
}
y se podía utilizar de esta manera:
class Program
{
public static void Main(string[] args)
{
//this could be your linq query
var qry = TestSlowLoadingEnumerable();
//We begin the call and give it our callback delegate
//and a delegate to an error handler
AsynchronousQueryExecutor.Call(qry, HandleResults, HandleError);
Console.WriteLine("Call began on seperate thread, execution continued");
Console.ReadLine();
}
public static void HandleResults(IEnumerable<int> results)
{
//the results are available in here
foreach (var item in results)
{
Console.WriteLine(item);
}
}
public static void HandleError(Exception ex)
{
Console.WriteLine("error");
}
//just a sample lazy loading enumerable
public static IEnumerable<int> TestSlowLoadingEnumerable()
{
Thread.Sleep(5000);
foreach (var i in new int[] { 1, 2, 3, 4, 5, 6 })
{
yield return i;
}
}
}
va a ir a poner esto en mi blog ahora, bastante práctico.
¿Funcionó bien la respuesta de abajo para usted? – TheSoftwareJedi
Consulte las extensiones reactivas para .NET en http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx, está diseñado para consultas Linq asincrónicas. –
De hecho, pero no Linq * a SQL * consultas que es lo que el autor está preguntando. –