C# 通用扩展的异步版本

C# 通用扩展的异步版本,c#,C#,在C#6中,我有以下扩展: public static void With<T>(this T value, Action<T> action) { action(value); } public static R With<T, R>(this T value, Func<T, R> function) { return function(value); } public static void With(此T值,动作){ 作用(价值

在C#6中,我有以下扩展:

public static void With<T>(this T value, Action<T> action) {
  action(value);
}

public static R With<T, R>(this T value, Func<T, R> function) {
  return function(value);
}
public static void With(此T值,动作){
作用(价值);
}
带有(此T值,Func函数)的公共静态R{
返回函数(值);
}
有没有办法获得这些扩展的异步版本

更新

我要加一个例子来澄清。考虑(上下文是EF上下文):

IList posts=context.posts.With(x=>x.ToList());
现在,如果我想使用ToListSync,该怎么做

IList<Post> posts = await context.Posts.WithAsync(x => x.ToListAsync());
IList posts=wait context.posts.WithAsync(x=>x.ToListAsync());

IList posts=context.posts.WithAsync(x=>wait x.ToListAsync());

最好的方法是什么?扩展是什么样子的?

只需像处理任何其他函数一样:

public static async Task With<T>(this T value, Func<T, Task> action) {
  await action(value);
}

public static async Task<R> With<T, R>(this T value, Func<T, Task<R>> function) {
  return await function(value);
}

公共静态异步任务(此T值,Func操作){
等待行动(价值);
}
具有(此T值,Func函数)的公共静态异步任务{
返回等待函数(值);
}

只需像处理任何其他功能一样:

public static async Task With<T>(this T value, Func<T, Task> action) {
  await action(value);
}

public static async Task<R> With<T, R>(this T value, Func<T, Task<R>> function) {
  return await function(value);
}

公共静态异步任务(此T值,Func操作){
等待行动(价值);
}
具有(此T值,Func函数)的公共静态异步任务{
返回等待函数(值);
}
  • 使其
    异步
  • 使其返回一个
    任务
    。如果您需要实际返回类型,请使用
    Task
    而不是
    Task
  • 为了更好地测量,请将其命名为
    with async
    。这将允许
    与异步实现共存,这也是常见的约定


publicstaticasync任务WithAsync(这个T值,Action)
{
等待动作异步(值);
}
  • 使其
    异步
  • 使其返回一个
    任务
    。如果您需要实际返回类型,请使用
    Task
    而不是
    Task
  • 为了更好地测量,请将其命名为
    with async
    。这将允许
    与异步实现共存,这也是常见的约定


publicstaticasync任务WithAsync(这个T值,Action)
{
等待动作异步(值);
}
提供一个返回任务的
函数
。您可以像
vary=wait x.With(asyncz=>{/*…*/})一样使用它

结论:您不需要做任何更改

提供一个返回任务的
函数
。您可以像
vary=wait x.With(asyncz=>{/*…*/})一样使用它


结论:您不需要进行任何更改。

我强烈建议不要在扩展方法中使用
async
/
wait
来跳过状态机的生成。只需返回任务并等待,或在需要时等待

对于异步情况,也可以使用第二种方法

public static R With<T>(this T value, Func<T, R> function) 
{
  return function(value);
}
public static R With(此T值,Func函数)
{
返回函数(值);
}
或者,您可以将约束方法仅用于异步使用

public static R WithAsync<T, R>(this T value, Func<T, R> function)
     where R : Task 
{
  return function(value);
}
publicstaticr WithAsync(此T值,Func函数)
其中R:Task
{
返回函数(值);
}

我强烈建议不要在扩展方法中使用
async
/
wait
来跳过状态机的生成。只需返回任务并等待,或在需要时等待

对于异步情况,也可以使用第二种方法

public static R With<T>(this T value, Func<T, R> function) 
{
  return function(value);
}
public static R With(此T值,Func函数)
{
返回函数(值);
}
或者,您可以将约束方法仅用于异步使用

public static R WithAsync<T, R>(this T value, Func<T, R> function)
     where R : Task 
{
  return function(value);
}
publicstaticr WithAsync(此T值,Func函数)
其中R:Task
{
返回函数(值);
}
我在上有一篇博文。总之,
Action
async
版本是
Func
,而
async
版本是
Func

我建议您提供所有重载以实现最大可用性:

public static void With<T>(this T value, Action<T> action) {
  action(value);
}

public static R With<T, R>(this T value, Func<T, R> function) {
  return function(value);
}

public static Task With<T>(this T value, Func<T, Task> function) {
  return function(value);
}

public static Task<R> With<T, R>(this T value, Func<T, Task<R>> function) {
  return function(value);
}
public static void With(此T值,动作){
作用(价值);
}
带有(此T值,Func函数)的公共静态R{
返回函数(值);
}
具有(此T值,Func函数)的公共静态任务{
返回函数(值);
}
具有(此T值,Func函数)的公共静态任务{
返回函数(值);
}
我在上有一篇博文。总之,
Action
async
版本是
Func
,而
async
版本是
Func

我建议您提供所有重载以实现最大可用性:

public static void With<T>(this T value, Action<T> action) {
  action(value);
}

public static R With<T, R>(this T value, Func<T, R> function) {
  return function(value);
}

public static Task With<T>(this T value, Func<T, Task> function) {
  return function(value);
}

public static Task<R> With<T, R>(this T value, Func<T, Task<R>> function) {
  return function(value);
}
public static void With(此T值,动作){
作用(价值);
}
带有(此T值,Func函数)的公共静态R{
返回函数(值);
}
具有(此T值,Func函数)的公共静态任务{
返回函数(值);
}
具有(此T值,Func函数)的公共静态任务{
返回函数(值);
}

这取决于您打算进行的处理量和处理方式

你需要一根线吗?如果是这样的话,那么使用Task提供了一个很好的线程替代方案

否则,线程池中可能已经有很多线程可供您使用,您可以使用“BeginInvoke”访问这些线程

static void _TestLogicForBeginInvoke(int i)
    {
        System.Threading.Thread.Sleep(10);

        System.Console.WriteLine("Tested");
    }

    static void _Callback(IAsyncResult iar)
    {
        System.Threading.Thread.Sleep(10); 

        System.Console.WriteLine("Callback " + iar.CompletedSynchronously);
    }

    static void TestBeginInvoke()
    {
        //Callback is written after Tested and NotDone.
        var call = new System.Action<int>(_TestLogicForBeginInvoke);

        //Start the call
        var callInvocation = call.BeginInvoke(0, _Callback, null);

        //Write output
        System.Console.WriteLine("Output");

        int times = 0;

        //Wait for the call to be completed a few times
        while (false == callInvocation.IsCompleted && ++times < 10)
        {
            System.Console.WriteLine("NotDone");
        }

        //Probably still not completed.
        System.Console.WriteLine("IsCompleted " + callInvocation.IsCompleted);

        //Can only be called once, should be called to free the thread assigned to calling the logic assoicated with BeginInvoke and the callback.
        call.EndInvoke(callInvocation);
    }//Callback 

可以使用委托实例的“BeginInvoke”方法在线程池上调用您定义的任何“委托”类型。另请参见

这取决于您打算进行的处理量和处理方式

你需要一根线吗?如果是这样的话,那么使用Task提供了一个很好的线程替代方案

否则,线程池中可能已经有很多线程可供您使用,您可以使用“BeginInvoke”访问这些线程

static void _TestLogicForBeginInvoke(int i)
    {
        System.Threading.Thread.Sleep(10);

        System.Console.WriteLine("Tested");
    }

    static void _Callback(IAsyncResult iar)
    {
        System.Threading.Thread.Sleep(10); 

        System.Console.WriteLine("Callback " + iar.CompletedSynchronously);
    }

    static void TestBeginInvoke()
    {
        //Callback is written after Tested and NotDone.
        var call = new System.Action<int>(_TestLogicForBeginInvoke);

        //Start the call
        var callInvocation = call.BeginInvoke(0, _Callback, null);

        //Write output
        System.Console.WriteLine("Output");

        int times = 0;

        //Wait for the call to be completed a few times
        while (false == callInvocation.IsCompleted && ++times < 10)
        {
            System.Console.WriteLine("NotDone");
        }

        //Probably still not completed.
        System.Console.WriteLine("IsCompleted " + callInvocation.IsCompleted);

        //Can only be called once, should be called to free the thread assigned to calling the logic assoicated with BeginInvoke and the callback.
        call.EndInvoke(callInvocation);
    }//Callback 

可以使用委托实例的“BeginInvoke”方法在线程池上调用您定义的任何“委托”类型。另请参见

BeginInvoke不会执行任何异步操作,相反,它会在执行时阻塞主线程
Output
NotDone
NotDone
NotDone
NotDone
NotDone
NotDone
NotDone
NotDone
NotDone
IsCompleted False
Tested
Callback False