Tag: 委托

将方法组隐式转换为Delegate(对于Control.Invoke的参数)

我正在使用Windows窗体应用程序,它包含自定义控件,这些控件可能会从UI线程以外的线程调用。 因此,这些方法看起来有点像这样以防止exception: public void DoSomeStuff() { if (InvokeRequired) { Invoke((Action)DoSomeStuff); } else { // Actually do some stuff. } } 方法组DoSomeStuff对Action的显式DoSomeStuff引起了我的注意,因此我一直在深入研究代表和其他相关主题。 虽然我在这里看到了一些相关的问题,但我还是找不到我的答案,这是: 为什么方法组DoSomeStuff在这种情况下需要显式转换为Action ? 如果我删除了演员,那么我会得到两个错误: 错误102参数1:无法从’方法组’转换为’System.Delegate’ 错误101’System.Windows.Forms.Control.Invoke(System.Delegate,params object [])’的最佳重载方法匹配有一些无效的参数 事实上编译器显然混淆了使用Invoke哪个重载似乎是一个相当大的提示,但我仍然不确定为什么它无法解决这个问题。 我希望编译器推断出Invoke的第一个重载是一个应该使用的,它接受一个Delegate参数。 我希望如果代码是这样编写的话没有问题: Action a = DoSomeStuff; Invoke(a); 方法组DoSomeStuff可以隐式转换为Action委托类型, Action从System.Delegate派生(技术上?),因此Invoke可以毫无困难地处理参数a 。 但是当我尝试直接将DoSomeStuff作为参数传递时,为什么编译器无法进行隐式转换呢? 说实话,我不相信我自己的逻辑,但我仍然不确定我错过了什么。

Silverlight中的同步操作

我有一个Silverlight应用程序,它使用操作从模型中获取数据(再次从WCF服务获取数据)。 我需要以某种方式同步两个ActionCallbacks,或等待它们,然后执行一些代码。 例: _model.GetMyTypeList(list => { MyTypeList.AddRange(list); }); _model.GetStigTypeList(list => { StigTypeList.AddRange(list); }); doSomethingWhenBothHaveReturned(); 我知道我可以使用计数器来记录已经返回的数量,但有没有更好的方法来做到这一点? 编辑: user24601有一个很好的答案,但在Silverlight,任何其他伟大的想法中不存在CountdownEvent? 🙂

C#代表,参考解析时间

我有一个关于.net委托的简单问题。 说我有这样的事情: public void Invoke(Action action) { Invoke(() => action(this.Value)); } public void Invoke(Action action) { m_TaskQueue.Enqueue(action); } 第一个函数包含对this.Value的引用。 在运行时,当第一个带有generics参数的方法被调用时,它会以某种方式提供this.Value到第二个,但是如何? 我想到了这些: 按值调用(struct) – 传递this.Value的当前值,因此如果m_TaskQueue在5分钟后执行它,则该值将不会处于其最近状态,它将是第一次引用时的值。 通过引用调用(引用类型) – 然后在执行操作期间引用最近的Value状态,但如果我在执行操作之前将this.Value更改为另一个引用,它仍将指向旧引用 按名称调用(两者) – 在this.Value将评估this.Value 。 我相信实际的实现将持有this的引用,然后在实际执行委托期间评估该Value ,因为没有按名称调用。 我认为这将是名称样式的调用,但无法找到任何文档,所以想知道它是否是一个明确定义的行为。 这个类类似于Scala或Erlang中的Actor,所以我需要它是线程安全的。 我不希望Invoke函数立即取消引用Value ,这将通过m_TaskQueue在this对象的安全线程中m_TaskQueue 。

条件语句,generics委托不必要的演员

设置Action值时,我在条件语句中遇到了这个非常奇怪的问题。 这不是我不知道如何解决这个问题,因为使用普通的if很容易解决。 这是我的问题: public class Test { public bool Foo { get; set; } public Action Action { get; set; } public void A() { Action = Foo ? B : C;//Gives compiler error } public void B(bool value) { } public void C(bool value) { } } 这给了我一条消息的编译器错误 “方法组”和“方法组”之间没有隐式转换。 这很奇怪,因为我无法弄清楚为什么这是非法的。 顺便说一句,下面的语法将使这个有效(从编译器的角度来看): public void A() […]

如何委托telerik网格视图从每个子页面的父页面调用常用方法?

我正在使用Telerik Gridview显示记录列表,我有超过10个页面 ,我正在使用此gridview以及以下常见事件代码复制粘贴(有一些小的更改)在所有这些页面上: protected void Page_Load(object sender, EventArgs e) { DisplayRecords() } public void DisplayRecords() { //Grid view names are different on different pages. GridView1.DataSource=Fetching records from database. GridView1.DataBind(); } protected void GridView1_SortCommand(object sender, GridSortCommandEventArgs e) { DisplayRecords() } protected void GridView1_PageIndexChanged(object sender, GridPageChangedEventArgs e) { var index = e.NewPageIndex; DisplayRecords() } protected void GridView1_PageSizeChanged(object […]

复制代表

我刚刚在MSDN上阅读有关事件的页面,我遇到了一段令我困惑的示例代码。 有问题的代码是这样的: // Make a temporary copy of the event to avoid possibility of // a race condition if the last subscriber unsubscribes // immediately after the null check and before the event is raised. EventHandler handler = RaiseCustomEvent; 我理解代码的意图,但我没有看到该特定行如何制作任何东西的副本。 它所做的只是复制参考 ; 它实际上并没有制作委托实例的深层副本。 所以为此,它实际上并没有完全阻止竞争条件。 我错过了一些明显的东西吗?

比较代表行动

随意质疑我的理智。 我需要确定Action vs Action是否是原始实例。 我所拥有的是一个带有类变量的类protected Action MessageCallback = null; 当我的abstract class Message是通过抽象方法创建的时候,我强制“他们”初始化MessageCallBack。 此MessageCallback被添加到IList<Action> 。 此列表中定义的每个操作可以不同。 现在,我想要做的是从列表中删除一个特定的操作,但我没有尝试比较它。 以下是我尝试过的最后一次设置的示例: public void Unsubscribe(Action messageCallback) { var messageType = typeof(TMessage); var callbackTypes = messageReceivedCallbacks .Keys .Where(k => k.IsAssignableFrom(messageType)); lock (messageReceivedCallbacks) { foreach (var callbackType in callbackTypes) { messageReceivedCallbacks[callbackType].Remove(new Action(m => messageCallback((TMessage)m))); } } } 我明白我想要做的事情可能是不可能的,但一般来说,我只是做一些不正当的事情,或者缺乏适当的知识,就像我想的那样。 提前感谢您提供的任何帮助。 尝试以下一些方法后更新: 比较他们一直在失败。 以下3项建议都不起作用。 […]

为什么后台线程中未处理的exception不会导致应用程序域崩溃?

我完全不解。 如果在我从未测试过的线程中有未捕获的exception,我非常确定.NET会关闭整个应用程序域。 但是我只是尝试了下面的代码并且它没有失败…任何人都可以解释为什么? (在.NET 4和3.5中尝试过) static void Main(string[] args) { Console.WriteLine(“Main thread {0}”, Thread.CurrentThread.ManagedThreadId); Action a = new Action(() => { Console.WriteLine(“Background thread {0}”, Thread.CurrentThread.ManagedThreadId); throw new ApplicationException(“test exception”); }); a.BeginInvoke(null, null); Console.ReadLine(); }

如何访问控件的事件?

我试图得到分配给控制的事件的名称例如:我有两个formsA和B. 表单B包含GridControl ,gridcontrol有一些事件,如gridControl1_Validating。 我的目标只是知道分配给控件的事件是什么 我的守则如下FOrm A. public Control[] FilterControls(Control start, Func isMatch) { var matches = new List(); Action filter = null; (filter = new Action(c => { if (isMatch(c)) matches.Add(c); foreach (Control c2 in c.Controls) filter(c2); }))(start); return matches.ToArray(); } static void main[] { Control[] FoundControls = null; FoundControls = FilterControls(TF, c => c.Name […]

如何将任何方法作为另一个函数的参数传递

在Aclass,我有 internal void AFoo(string s, Method DoOtherThing) { if (something) { //do something } else DoOtherThing(); } 现在我需要能够将DoOtherThing传递给AFoo() 。 我的要求是DoOtherThing可以有任何返回类型的签名几乎总是无效。 类似于B类的东西, void Foo() { new ClassA().AFoo(“hi”, BFoo); } void BFoo(//could be anything) { } 我知道我可以通过Action或实现代表来实现这一点(如许多其他SOpost中所见)但如果B类函数的签名未知,怎么能实现呢?