如何编写扩展方法,这将使多播C#委托中的调用列表成员顺序运行? [英] How to write extension method which will make invocation list members in multicast C# delegate run sequentially?

查看:414
本文介绍了如何编写扩展方法,这将使多播C#委托中的调用列表成员顺序运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个异步代理,等待异步方法:

 异步任务M1()
{
Debug.WriteLine(M1.A);
等待Task.Delay(10);
Debug.WriteLine(M1.B);
}

异步任务M2()
{
Debug.WriteLine(M2.A);
等待Task.Delay(1);
Debug.WriteLine(M2.B);
}

委托任务MyDel();

async void button_Click(object sender,RoutedEventArgs e)
{
MyDel del = null;
del + = M1;
del + = M2;
await del();
}

输出是:

  M1.A 
M2.A
M2.B
M1.B

也就是说,两个调用成员同时关闭,不等待对方。我需要他们等待对方,所以输出将是:

  M1.A 
M1.B
M2.A
M2.B

我试过这个代替 await del()

  foreach(del.GetInvocationList()中的MyDel成员)
{
await member();
}

这个工作。但是,我有很多代码的地方需要完成。代表可以有不同类型的参数数量不同,但都返回任务



如何编写扩展名方法,让我通过这样的调用来运行代码?

  del0.AwaitOneByOne(); // del0是'delegate Task Method()'
del1.AwaitOneByOne(paramInt1,paramStr2); // del1是'delegate Task Method(int,string)'
del2.AwaitOneByOne(paramBytes1); // del2是委托任务方法(byte [])'


解决方案

如果您为代理而不是自定义代理使用Func,则可以编写以下内容:

  public static class FuncHelper 
{
public static async任务RunSequential< T1>(此Func< T1,Task> del,T1 param1)
{
foreach(var d in del.GetInvocationList()。OfType< ; Func< T1,Task>>())
{
await d(param1);
}
}

public static async任务RunSequential< T1,T2>(此Func {
foreach(var d in del.GetInvocationList()。OfType< Func< T1,T2,Task>>())
{
await d(param1,param2);
}
}

//更多参数的其他方法到这里

}

似乎您正在尝试以不真正意图的方式使用代理。他们不是真的要控制秩序或让功能相互依赖完成。



可能更好的做一个自定义集合,可能覆盖+ =和 - =如果你想要一些代理人的行为。


I have an async delegate which I await in the async method:

async Task M1()
{
    Debug.WriteLine("M1.A");
    await Task.Delay(10);
    Debug.WriteLine("M1.B");
}

async Task M2()
{
    Debug.WriteLine("M2.A");
    await Task.Delay(1);
    Debug.WriteLine("M2.B");
}

delegate Task MyDel();

async void button_Click(object sender, RoutedEventArgs e)
{
    MyDel del = null;
    del += M1;
    del += M2;
    await del();
}

The output is:

M1.A
M2.A
M2.B
M1.B

That is, both invocation members go off simultaneously, not awaiting each other. I need them await each other so the output would be:

M1.A
M1.B
M2.A
M2.B

I tried this in place of await del():

foreach (MyDel member in del.GetInvocationList())
{
    await member();
}

This works. However, I have lots of code places where this needs to be done. Delegates can have different number of parameters of various types but they all return Task.

How can I write an extension method which will let me run the code above by making calls like this?

del0.AwaitOneByOne(); // del0 is 'delegate Task Method()'
del1.AwaitOneByOne(paramInt1, paramStr2); // del1 is 'delegate Task Method(int, string)'
del2.AwaitOneByOne(paramBytes1); // del2 is 'delegate Task Method(byte[])'

解决方案

If you use Func for you delegates rather than custom delegates you could write something like this:

public static class FuncHelper
{
    public static async Task RunSequential<T1>(this Func<T1,Task> del, T1 param1)
    {       
        foreach (var d in del.GetInvocationList().OfType<Func<T1, Task>>())
        {
            await d(param1);
        }
    }

    public static async Task RunSequential<T1, T2>(this Func<T1, T2, Task> del, T1 param1, T2 param2)
    {
        foreach (var d in del.GetInvocationList().OfType<Func<T1, T2, Task>>())
        {
            await d(param1, param2);
        }
    }

// Additional methods for more parameters go here

}

It does seem that you are trying to use delegates in ways they were not really intended. They aren't really supposed to control order or have the functions rely on each other to complete.

Probably better off making a custom collection, maybe override += and -= if you want some delegate like behavior.

这篇关于如何编写扩展方法,这将使多播C#委托中的调用列表成员顺序运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆