struct/IDisposable/MessageBox.Show()

R

Robert Heuvel

Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 
R

Robert Heuvel

haha, it works without working...
Dispose is never called, the cursor gets reset to previous state without Dipose being responsible... sorry
Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 
N

Nicholas Paldino [.NET/C# MVP]

Robert,

You are implementing the pattern incorrectly. First, your structure should look like this:


public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

The reason for this is that if you don't declare it as a public method (instead of an explicit interface implementation), it will incur a boxing operation (in .NET 2.0 it will, not in 1.1 and before, I believe), which you don't want.

Furthermore, your event handler should look like this:

private void btnCursorTest_Click(object sender, System.EventArgs e) {
using (SWaitCursor WC = new SWaitCursor(1))
{
System.Threading.Thread.Sleep(1000);
}
}

If you implement IDisposable, then you need to use it in a using statement to get the deterministic behavior. The way you have it, the structure is just popped off the stack, which is why your call to MessageBox never occurs.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 
R

Robert Heuvel

HI,

one question:

void Dispose() instead of void System.IDisposable.Dispose() (as VS2003 generated itself) would prevent boxing?
Could you explain that one please?

As to using the using clause, sure thing, but then it would make more sense to use a class because the constructor wouldn't need a useless parameter.

And what about the cursor behaviour? Is it normal for it to revert to Cursor.Default after the completion on an event handling call?
Robert,

You are implementing the pattern incorrectly. First, your structure should look like this:


public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

The reason for this is that if you don't declare it as a public method (instead of an explicit interface implementation), it will incur a boxing operation (in .NET 2.0 it will, not in 1.1 and before, I believe), which you don't want.

Furthermore, your event handler should look like this:

private void btnCursorTest_Click(object sender, System.EventArgs e) {
using (SWaitCursor WC = new SWaitCursor(1))
{
System.Threading.Thread.Sleep(1000);
}
}

If you implement IDisposable, then you need to use it in a using statement to get the deterministic behavior. The way you have it, the structure is just popped off the stack, which is why your call to MessageBox never occurs.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 
N

Nicholas Paldino [.NET/C# MVP]

Robert,

In .NET 2.0, if you implement a method on an interface implicitly, the compiler will generate an IL instruction which will call the method on the structure, without a cast to IDisposable. Otherwise, a cast to IDisposable will take place, causing a boxing operation.

If you look at the attached piece of code in Reflector, you will see what I mean.

To get around the parameter issue, you could do this:

public struct SWaitCursor:IDisposable {
public static SWaitCursor Create() {
// Set the cursor.
Cursor.Current = Cursors.WaitCursor;

return new SWaitCursor();
}

void Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

And then use it in the using statement.

I'm not sure about the Cursor being set after an event handler. It is possible, but I can't say for sure.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
HI,

one question:

void Dispose() instead of void System.IDisposable.Dispose() (as VS2003 generated itself) would prevent boxing?
Could you explain that one please?

As to using the using clause, sure thing, but then it would make more sense to use a class because the constructor wouldn't need a useless parameter.

And what about the cursor behaviour? Is it normal for it to revert to Cursor.Default after the completion on an event handling call?
Robert,

You are implementing the pattern incorrectly. First, your structure should look like this:


public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

The reason for this is that if you don't declare it as a public method (instead of an explicit interface implementation), it will incur a boxing operation (in .NET 2.0 it will, not in 1.1 and before, I believe), which you don't want.

Furthermore, your event handler should look like this:

private void btnCursorTest_Click(object sender, System.EventArgs e) {
using (SWaitCursor WC = new SWaitCursor(1))
{
System.Threading.Thread.Sleep(1000);
}
}

If you implement IDisposable, then you need to use it in a using statement to get the deterministic behavior. The way you have it, the structure is just popped off the stack, which is why your call to MessageBox never occurs.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 
N

Nicholas Paldino [.NET/C# MVP]

Oops, here is the code.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
HI,

one question:

void Dispose() instead of void System.IDisposable.Dispose() (as VS2003 generated itself) would prevent boxing?
Could you explain that one please?

As to using the using clause, sure thing, but then it would make more sense to use a class because the constructor wouldn't need a useless parameter.

And what about the cursor behaviour? Is it normal for it to revert to Cursor.Default after the completion on an event handling call?
Robert,

You are implementing the pattern incorrectly. First, your structure should look like this:


public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

The reason for this is that if you don't declare it as a public method (instead of an explicit interface implementation), it will incur a boxing operation (in .NET 2.0 it will, not in 1.1 and before, I believe), which you don't want.

Furthermore, your event handler should look like this:

private void btnCursorTest_Click(object sender, System.EventArgs e) {
using (SWaitCursor WC = new SWaitCursor(1))
{
System.Threading.Thread.Sleep(1000);
}
}

If you implement IDisposable, then you need to use it in a using statement to get the deterministic behavior. The way you have it, the structure is just popped off the stack, which is why your call to MessageBox never occurs.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

this is what I did:

public struct SWaitCursor:IDisposable {
public SWaitCursor (int i) {
Cursor.Current = Cursors.WaitCursor;
}
void System.IDisposable.Dispose() {
Cursor.Current = Cursors.Default;
MessageBox.Show("SWaitCursor.Dispose");
}
}

private void btnCursorTest_Click(object sender, System.EventArgs e) {
SWaitCursor WC = new SWaitCursor(1);
System.Threading.Thread.Sleep(1000);
}

what I want to know:

- Is it definite that in btnCursorTest_Click the object WC will be disposed of (calling the Dispose method) always AND exactly at the same time the method returns?
- Wondering why MessageBox.Show() in Dispose doesn't execute, breakpoints don't work either??

It seems to work though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top