相关疑难解决方法(0)

如何删除lambda事件处理程序

可能重复:
在C#中取消订阅匿名方法
如何取消注册"匿名"事件处理程序

我最近发现我可以使用lambdas来创建简单的事件处理程序.我可以订阅像这样的点击事件:

button.Click += (s, e) => MessageBox.Show("Woho");
Run Code Online (Sandbox Code Playgroud)

但你怎么取消订阅呢?

c# events lambda event-handling

223
推荐指数
1
解决办法
8万
查看次数

在C#中取消订阅匿名方法

是否可以从事件中取消订阅匿名方法?

如果我订阅这样的事件:

void MyMethod()
{
    Console.WriteLine("I did it!");
}

MyEvent += MyMethod;
Run Code Online (Sandbox Code Playgroud)

我可以这样取消订阅:

MyEvent -= MyMethod;
Run Code Online (Sandbox Code Playgroud)

但是如果我使用匿名方法订阅:

MyEvent += delegate(){Console.WriteLine("I did it!");};
Run Code Online (Sandbox Code Playgroud)

是否有可能取消订阅这种匿名方法?如果是这样,怎么样?

c# delegates anonymous-methods

214
推荐指数
7
解决办法
7万
查看次数

如何取消注册"匿名"事件处理程序

说如果我听一个事件:

Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
    //some code
}); 
Run Code Online (Sandbox Code Playgroud)

现在我如何取消注册此活动?或者只是让内存泄漏?

.net c# events delegates anonymous-methods

37
推荐指数
4
解决办法
2万
查看次数

如何取消订阅使用lambda表达式的事件?

我有以下代码让GUI响应集合中的更改.

myObservableCollection.CollectionChanged += ((sender, e) => UpdateMyUI());
Run Code Online (Sandbox Code Playgroud)

首先,这是一个很好的方法吗?

第二:取消订阅此活动的代码是什么?它是相同的但是 - =(然后又是完整的匿名方法)?

.net c# lambda event-handling c#-3.0

26
推荐指数
2
解决办法
1万
查看次数

.NET中的弱事件?

如果对象A侦听来自对象B的事件,则对象B将使对象A保持活动状态.是否存在可以阻止这种情况的弱事件的标准实现?我知道WPF有一些机制,但我正在寻找与WPF无关的东西.我猜测解决方案应该在某处使用弱引用.

.net events garbage-collection weak-references

26
推荐指数
2
解决办法
7159
查看次数

使用lambdas作为事件处理程序会导致内存泄漏吗?

假设我们有以下方法:

private MyObject foo = new MyObject();

// and later in the class

public void PotentialMemoryLeaker(){
  int firedCount = 0;
  foo.AnEvent += (o,e) => { firedCount++;Console.Write(firedCount);};
  foo.MethodThatFiresAnEvent();
}
Run Code Online (Sandbox Code Playgroud)

如果实例化具有此方法的类并且PotentialMemoryLeaker多次调用该方法,那么我们是否会泄漏内存?

在我们完成调用之后有没有办法取消挂起lambda事件处理程序MethodThatFiresAnEvent

lambda memory-leaks event-handling

20
推荐指数
1
解决办法
5978
查看次数

使用匿名委托进行事件处理时的垃圾收集

UPDATE

我将这里的各种答案结合到一个新问题的"确定"答案中.

原始问题

在我的代码中,我有一个事件发布者,它在应用程序的整个生命周期中都存在(这里简化为基本要素):

public class Publisher
{
    //ValueEventArgs<T> inherits from EventArgs
    public event EventHandler<ValueEventArgs<bool>> EnabledChanged; 
}
Run Code Online (Sandbox Code Playgroud)

因为这个发布者可以在所有地方使用,所以我对自己创建这个小帮助类非常满意,以避免在所有订阅者中重写处理代码:

public static class Linker
{
    public static void Link(Publisher publisher, Control subscriber)
    {
         publisher.EnabledChanged += (s, e) => subscriber.Enabled = e.Value;
    }

    //(Non-lambda version, if you're not comfortable with lambdas)
    public static void Link(Publisher publisher, Control subscriber)
    {
         publisher.EnabledChanged +=
             delegate(object sender, ValueEventArgs<bool> e)
             {
                  subscriber.Enabled = e.Value;
             };
    }
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,直到我开始在较小的机器上使用它,当我偶尔开始:

System.ComponentModel.Win32Exception
Not enough storage is available to process …
Run Code Online (Sandbox Code Playgroud)

c# garbage-collection event-handling

13
推荐指数
2
解决办法
1万
查看次数

One Liner:WeakReference-to-a Lambda事件处理程序

除了多次使用它会违反DRY原则这个事实之外,你能否看到这种单线的缺点?这似乎很简单,但我没有看到其他人提出它的事实让我想知道它是否有缺点.

这段代码创建一个方法的WeakReference,然后注册一个调用引用目标的事件处理程序.

SomeEvent += (sender, e) => ((Action)(new WeakReference((Action)ProcessEvent)).Target)();
Run Code Online (Sandbox Code Playgroud)

谢谢,

.net c# lambda weak-references event-handling

9
推荐指数
1
解决办法
3411
查看次数

为什么在从UI中删除命令源后调用CanExecute?

我试图理解为什么在已从UI中删除的命令源上调用CanExecute.这是一个简化的程序来演示:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="350" Width="525">
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button Content="{Binding Txt}" 
                                Command="{Binding Act}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Remove first item" Click="Button_Click"  />
    </StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)

代码隐藏:

public partial class MainWindow : Window
{
    public class Foo
    {
        static int _seq = 0;
        int _txt = _seq++;
        RelayCommand _act;
        public bool Removed = false;

        public string Txt { get { return _txt.ToString(); } }

        public ICommand Act
        {
            get
            {
                if (_act == null) …
Run Code Online (Sandbox Code Playgroud)

.net c# wpf binding mvvm

6
推荐指数
1
解决办法
2080
查看次数

在 CustomControls 中取消订阅事件的模式

我正在开发一个自定义控件,它在内部订阅 Touch.FrameReported - 一个静态事件。这有可能导致内存泄漏(在某些情况下确实如此)。

这是我目前的解决方案。在加载/卸载事件中订阅/取消订阅。但是,我发现 Unloaded 事件并不总是被调用。这可能会导致内存泄漏。

// Imagine this is a CustomControl, to be consumed by users 
// with no regard for calling Dispose
public class CustomGrid : Grid
{   
    public CustomGrid()
    {
        Loaded += (s, a) =>
                  {
                      Touch.FrameReported -= OnTouchFrameReported;
                      Touch.FrameReported += OnTouchFrameReported;
                  };

        Unloaded += (s, a) =>
                  {
                    // The intention is to unsubscribe on unload, which should pre-date
                    // user intended 'disposal' of the control
                    Touch.FrameReported -= OnTouchFrameReported;
                  };
    }
Run Code Online (Sandbox Code Playgroud)

有没有已知的模式来解决这个问题?取消订阅自定义控件“拆卸”中的事件?我已经尝试过:

  • 在卸载时取消订阅。并不总是被调用。
  • 处置。无法使用,因为用户可能无法确定性地调用 Dispose …

c# wpf events memory-leaks windows-runtime

6
推荐指数
1
解决办法
1125
查看次数

在C#中使用Lambda的UnHooking事件#

我经常遇到想要订阅事件的情况,但我想使用lambda来执行此操作:

public class Observable
{
    public event EventHandler SomethingHappened;

    public void DoSomething()
    {
        // Do Something...
        OnSomethingHappened();
    }
}

// Somewhere else, I hook the event
observable.SomethingHappened += (sender, args) => Console.WriteLine("Something Happened");
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我不知道如何取消事件.由于lambda在引擎盖下创建了一个匿名委托,所以我没有什么可以调用-=的.

现在,我可以创建一个方法:

private void SomethingHappened(object sender, EventArgs args)
{
    Console.WriteLine("Something Happened");
}
Run Code Online (Sandbox Code Playgroud)

然后我可以挂钩/取消所有我想要的东西:

observable.SomethingHappened += SomethingHappened;
observable.SomethingHappened -= SomethingHappened;
Run Code Online (Sandbox Code Playgroud)

但我真的非常非常喜欢使用我的lambda.在一个更复杂的例子中,lambdas在这里非常方便.

我很确定我运气不好......但我想知道是否有人想出办法做到这一点?

c# events lambda

5
推荐指数
2
解决办法
3355
查看次数

C#代码语法中的"s"和"e"是什么

我看到一些像这样的代码:

textBox.TextChanged += (s, e) => this.Foo();
Run Code Online (Sandbox Code Playgroud)

但我不知道"s"和"e"是什么?我应该在C#中学习这行代码的主题是什么?

c#

5
推荐指数
1
解决办法
481
查看次数