Надлежащий способ сгенерировать события в платформе.NET

Попробуйте перекрасить или повторно проверить после обновления:

textField.repaint();

Или, возможно:

textField.revalidate();

Проверить: https://docs.oracle.com/javase/tutorial /uiswing/painting/problems.html

28
задан 4 revs, 2 users 98% 23 May 2017 в 11:48
поделиться

5 ответов

Что бы это ни стоило, вам действительно стоит изучить класс EventsHelper Ювала Лоуи, а не делать что-то самостоятельно.

0
ответ дан 28 November 2019 в 03:25
поделиться

"Just because you have initialized the event with an empty delegate does not mean that a user of your class won't set it to null at some point and break your code."

Can't happen. Events "can only appear on the left hand side of += or -= (except when used from within the type)" to quote the error you'll get when doing this. Granted, the "except when used from within the type" makes this a theoretical possibility, but not one that any sane developer would be concerned with.

15
ответ дан 28 November 2019 в 03:25
поделиться

I raised the same issue about a week ago and reached the opposite conclusion:

C# Events and Thread Safety

Your summary doesn't do anything to persuade me otherwise!

First, clients of the class cannot assign null to the event. That's the whole point of the event keyword. Without that keyword, it would be a field holding a delegate. With it, all operations on it are private except enlisting and delisting.

As a result, assigning delegate {} to the event at construction completely meets the requirements of a correct implementation of an event source.

Of course, within the class there may be a bug where the event is set to null. However, in any class that contains a field of any type, there may be a bug that sets the field to null. Would you advocate that every time ANY member field of a class is accessed, we write code like this?

// field declaration:
private string customerName;

private void Foo()
{
    string copyOfCustomerName = customerName;
    if (copyOfCustomerName != null)
    {
        // Now we can use copyOfCustomerName safely...
    }
}

Of course you wouldn't. All programs would become twice as long and half as readable, for no good reason. The same madness occurs when people apply this "solution" to events. Events are not public for assignment, the same as private fields, and so it is safe to use them directly, as long as you initialize them to the empty delegate on construction.

The one situation you cannot do this in is when you have an event in a struct, but that's not exactly an inconvenience, as events tend to appear on mutable objects (indicating a change in the state) and structs are notoriously trick if allowed to mutate, so are best made immutable, and hence events are of little use with structs.

There may exist another quite separate race condition, as I described in my question: what if the client (the event sink) wants to be sure that their handler will not be called after it has been delisted? But as Eric Lippert pointed out, that is the responsibility of the client to solve. In short: it is impossible to guarantee that an event handler will not be called after it has been delisted. This is an inevitable consequence of delegates being immutable. This is true whether threads are involved or not.

In Eric Lippert's blog post, he links to my SO question, but then states a different but similar question. He did this for a legitimate rhetorical purpose, I think - just in order to set the scene for a discussion about the secondary race condition, the one affecting the handlers of the event. But unfortunately, if you follow the link to my question, and then read his blog post a little carelessly, you might get the impression that he is dismissing the "empty delegate" technique.

In fact, he says "There are other ways to solve this problem; for example, initializing the handler to have an empty action that is never removed", which is the "empty delegate" technique.

He covers "doing a null check" because it is "the standard pattern"; my question was, why is this the standard pattern? Jon Skeet suggested that given that the advice predates anonymous functions being added to the language, it's probably just a hangover from C# version 1, and I think that is almost certainly true, so I accepted his answer.

26
ответ дан 28 November 2019 в 03:25
поделиться

В качестве примечания, http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx

Это постоянная ссылка на статью, на которую ссылался Эрик.

1
ответ дан 28 November 2019 в 03:25
поделиться

Brumme is the daddy for both Eric and Abrams.. you should read his blog rather than preaching from either of the two publicists. The guy is seriously technical (as opposed to high-level hair-stylists logos ). He will give you a proper explanation without 'Redmond Flowers in 1TB land' on why races and memory models are a challenge for a managed (re: shield-the-children) environment as raised by another poster above.

Btw, it all starts with them, the C++ CLR implementation guys:

blogs.msdn.com/cbrumme

-1
ответ дан 28 November 2019 в 03:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: