我已经阅读了很多文章,但我仍然不清楚我们通常创建的普通代表和多播代理之间的区别.
public delegate void MyMethodHandler(object sender);
MyMethodHandler handler = new MyMethodHandler(Method1);
handler += Method2;
handler(someObject);
Run Code Online (Sandbox Code Playgroud)
上面的委托MyMethodHandler将调用这两个方法.现在多播代表的位置在哪里.我已经读过它们可以调用多种方法,但我担心我对代理的基本理解是不正确的.
根据Jon Skeet的说法,"您只能在具有单个目标调用的委托上调用BeginInvoke."
这是为什么?真正的原因是什么?
注意:为了澄清(因为我犯了这个错误),我说的BeginInvoke是代表,而不是控件.
我试图在Swift中实现多播委托功能.在Objective C中,我们有这个出色的实现
https://github.com/robbiehanson/XMPPFramework/blob/master/Utilities/GCDMulticastDelegate.m
我刚刚创建了这个基本功能:
protocol MyProtocol : class{
func testString()-> String;
}
class MulticastDelegateNode <T:AnyObject> {
weak var delegate : T?
init(object : T){
self.delegate = object;
}
}
class MulticastDelegate <T:AnyObject> {
var delegates = Array<MulticastDelegateNode<T>>()
func addDelegate(delegate : T){
var newNode = MulticastDelegateNode(object : delegate);
delegates.append(newNode);
}
func removeDelegate(delegate : AnyObject){
self.delegates = self.delegates.filter({ (node : MulticastDelegateNode) -> Bool in
return node.delegate !== delegate;
});
}
}
class OP {
var delegate = MulticastDelegate<MyProtocol>();
func process(){
//...
//make …Run Code Online (Sandbox Code Playgroud) 我觉得答案是否定的?如果没有,我们为什么要分开Delegate和MulticastDelegate上课?也许是因为"其他一些.NET语言"?
多播代理必须具有返回类型void否则将引发异常.
我想知道它背后的原因是什么,如果多个方法可以具有与委托相同的返回类型呢?
我已经获得了一些通过多播委托调用的代码。
我想知道如何赶上并管理那里引发的任何异常,但目前尚未管理。我无法修改给定的代码。
我一直在四处寻找,发现需要调用 GetInitationList() 但不太确定这是否有帮助。
我有一个仅在生产环境中发生的非常奇怪的问题。异常有消息
“委托给实例方法不能有 null 'this'”。
抛出异常的方法非常简单,并且工作了很长时间,所以问题一定是环境中的模糊依赖,或者类似的东西......
我正在使用托管在 Azure 中的 ASP.NET Web API,控制器的操作方法是通过 AJAX 执行的。
这是抛出异常的代码:
public class BlacklistService : IBlacklistService
{
public bool Verify(string blacklist, string message)
{
if (string.IsNullOrEmpty(blacklist)) return true;
var split = blacklist.ToLower().Split(';'); // exception is thrown here
return !split.Any(message.Contains);
}
}
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪的相关部分:
at System.MulticastDelegate.ThrowNullThisInDelegateToInstance()
at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr)
at MyApp.Business.Services.BlacklistService.Verify(String blacklist, String message)
at MyApp.Business.Services.ContactMessageFactory.GetVerifiedStatus(String mensagem)
at MyApp.Business.Services.ContactMessageFactory.GetMailMessage(ContactForm contactForm)
at MyApp.Business.ContactEmailService.Send(ContactForm contactForm)
Run Code Online (Sandbox Code Playgroud)
有人可以找出导致此异常的可能原因吗?提前致谢。
关于委托类型,我有一个非常基本的问题.我在对象浏览器中比较了Delegate和MulticastDelegate类的成员,我在MulticastDelegate中找不到任何新的附加成员.我还注意到Delegate类有GetInvocationList虚方法.所以我假设Delegate类应该能够保存对多个方法的引用.如果我的假设是正确的,我想知道为什么自定义委托类型不直接派生自Delegate类而不是MulticastDelegate类.不知道我在这里缺少什么.请帮我理解其中的区别.
何时通过单播代表进行多播委托是否有用?
我使用代理很多,主要是与C#lambdas结合使用,但我从未感觉到使用C#委托的多播方面的冲动,即我从来没有想过在一个委托中将多个委托组合在一起.因此,我很好奇多播代表在什么样的情况下是有用的 - 我只能想到你可以通过其他方式轻松实现功能的例子,比如链接代表或将它们放在列表中.
特别是,Eric Lippert 在这里给出的答案给人的印象是,即使C#团队有时会忘记代表的多播性.
我正在寻找可能对此有更多了解的人,我的直觉告诉我答案是“不,它不是线程安全的”,但我想确定。
为了说明我的问题,我为此类提供了一些背景信息
public class MyContext
{
private readonly object _lock = new object();
public delegate bool MyDelegate(MyContext context);
private MyDelegate _multicastDelegate;
public MyContext()
{
_multicastDelegate = null;
}
public void AddDelegate(MyDelegate del)
{
lock(_lock)
{
_multicastDelegate += del;
}
}
public void RemoveDelegate(MyDelegate del)
{
lock(_lock)
{
_multicastDelegate += del;
}
}
public void Go()
{
_multicastDelegate.Invoke(this);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我在上面的示例中添加了锁,但这实际上不是我的问题的重点。
我试图更好地了解保存调用列表的数组是否是线程安全的。坦白说,我不清楚这是如何组合在一起的,可以提供一些帮助。
根据我发现的文档,唯一没有提供真正洞察力的报价如下:
MulticastDelegate具有由一个或多个元素组成的委托链接列表,称为调用列表。调用多播委托时,调用列表中的委托按照它们出现的顺序被同步调用。如果在执行列表期间发生错误,则会引发异常。
https://msdn.microsoft.com/zh-CN/library/system.multicastdelegate.aspx
提前致谢。