My view:
If a setter or getter is expected to be expensive, don't make it a property, make it a method.
If setting a property triggers events due to changes, this is fine. How else would you allow listeners to be notified of changes? However, you may want to offer a BeginInit/EndInit pair to suppress events until all changes are made. Normally, it is the responsibility of the event handler to return promptly, but if you really can't trust it to do so, then you may wish to signal the event in another thread.
If setting a property throws exceptions on invalid values, it's also fine. This is a reasonable way to signal the problem when the value is completely wrong. In other cases, you set a bunch of properties and then call a method that uses them to do something, such as make a connection. This would allow holding off validation and error-handling until the properties are used, so the properties would not need to throw anything.
Accessing a property may have side-effects so long as they aren't unexpected and don't matter. This means a JIT instantiation in a getter is fine. Likewise, setting a dirty flag for the instance whenever a change is made is just fine, as it setting a related property, such as a different format for the same value.
If it does something as opposed to just accessing a value, it should be a method. Method are verbs, so creating a connection would be done by the OpenConnection() method, not a Connection property. A Connection property would be used to retrieve the connection in use, or to bind the instance to another connection.
edit - added 5, changed 2 and 3