New to threading. Need suggestions

M

MS

Hi. I'm new to developing and c#.

I'm developing a tool that allows a user to select a directory with
specially formatted files. The tool then iterates through the list of files
in the directory and sends their content via msmq. The part that iterates
and sends the files is in a separate thread. I have a button on the form
that allows the user to pause or resume the sending of these files. I'm
currently using thread.suspend and thread.resume for this. In the .NET
Framework 2.0 documentation it states that these methods are now deprecated.

How else can I achieve this functionality without using these methods?

Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

MS,

I would use a ManualResetEvent for this. Basically, you would create
the ManualResetEvent initially setting the state to signaled (there is a
constructor that you can pass true to in order to achieve this).

Then, in your worker thread, on each iteration of the loop, you call
WaitOne on the event (the event is shared between the threads, obviously).
Since it is a ManualResetEvent, the call to WaitOne will return immediately.

When you want to pause, you just call Reset on the ManualResetEvent, and
it will set the event to non-signaled. Then, on the next iteration of the
loop, your thread will pause. When you want to resume, just call Set on the
event.

This is actually cleaner than using Suspend and Resume, since it will
allow you to go through one iteration of your loop, and not leave file
handles open and the like.

Hope this helps.
 
M

MS

Thanks Nicholas. I got it working using ManualResetEvent even though I don't
quite understand what it does. I'll read up on it. This represents what I
have on my form. Am I doing it right?

private class form....
ManualResetEvent manualEvent;.
..
..
private void InitializeComponent()
this.manualEvent = new ManualResetEvent(true);
..
..
private void ProcessFiles...
create new thread and start it (runs method called Send)
..
..
private void send....
{
manualEvent.Set()
foreach(file in collection)
{
send the file;
manualEvent.WaitOne();
}
}

private void btnPause()
{
if(not paused)
manualEvent.Reset();
else
manualEvent.Set();
}


Nicholas Paldino said:
MS,

I would use a ManualResetEvent for this. Basically, you would create
the ManualResetEvent initially setting the state to signaled (there is a
constructor that you can pass true to in order to achieve this).

Then, in your worker thread, on each iteration of the loop, you call
WaitOne on the event (the event is shared between the threads, obviously).
Since it is a ManualResetEvent, the call to WaitOne will return
immediately.

When you want to pause, you just call Reset on the ManualResetEvent,
and it will set the event to non-signaled. Then, on the next iteration of
the loop, your thread will pause. When you want to resume, just call Set
on the event.

This is actually cleaner than using Suspend and Resume, since it will
allow you to go through one iteration of your loop, and not leave file
handles open and the like.

Hope this helps.


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

MS said:
Hi. I'm new to developing and c#.

I'm developing a tool that allows a user to select a directory with
specially formatted files. The tool then iterates through the list of
files in the directory and sends their content via msmq. The part that
iterates and sends the files is in a separate thread. I have a button on
the form that allows the user to pause or resume the sending of these
files. I'm currently using thread.suspend and thread.resume for this. In
the .NET Framework 2.0 documentation it states that these methods are now
deprecated.

How else can I achieve this functionality without using these methods?

Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

MS,

You are almost there. In the send method (which is called on the non-UI
thread, I assume), you don't want to call Set before you start looping.

Also, you don't want to call WaitOne after you send the file, but
before. This way, if you end, and hit pause before you finish, you dont
hold up the thread when there is nothing left to do.

Finally, call Set before you start the thread, and after that, you
should be fine.


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

MS said:
Thanks Nicholas. I got it working using ManualResetEvent even though I
don't quite understand what it does. I'll read up on it. This represents
what I have on my form. Am I doing it right?

private class form....
ManualResetEvent manualEvent;.
.
.
private void InitializeComponent()
this.manualEvent = new ManualResetEvent(true);
.
.
private void ProcessFiles...
create new thread and start it (runs method called Send)
.
.
private void send....
{
manualEvent.Set()
foreach(file in collection)
{
send the file;
manualEvent.WaitOne();
}
}

private void btnPause()
{
if(not paused)
manualEvent.Reset();
else
manualEvent.Set();
}


Nicholas Paldino said:
MS,

I would use a ManualResetEvent for this. Basically, you would create
the ManualResetEvent initially setting the state to signaled (there is a
constructor that you can pass true to in order to achieve this).

Then, in your worker thread, on each iteration of the loop, you call
WaitOne on the event (the event is shared between the threads,
obviously). Since it is a ManualResetEvent, the call to WaitOne will
return immediately.

When you want to pause, you just call Reset on the ManualResetEvent,
and it will set the event to non-signaled. Then, on the next iteration
of the loop, your thread will pause. When you want to resume, just call
Set on the event.

This is actually cleaner than using Suspend and Resume, since it will
allow you to go through one iteration of your loop, and not leave file
handles open and the like.

Hope this helps.


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

MS said:
Hi. I'm new to developing and c#.

I'm developing a tool that allows a user to select a directory with
specially formatted files. The tool then iterates through the list of
files in the directory and sends their content via msmq. The part that
iterates and sends the files is in a separate thread. I have a button on
the form that allows the user to pause or resume the sending of these
files. I'm currently using thread.suspend and thread.resume for this. In
the .NET Framework 2.0 documentation it states that these methods are
now deprecated.

How else can I achieve this functionality without using these methods?

Thanks!
 
?

=?ISO-8859-1?Q?Lasse_V=E5gs=E6ther_Karlsen?=

MS said:
Hi. I'm new to developing and c#.

I'm developing a tool that allows a user to select a directory with
specially formatted files. The tool then iterates through the list of files
in the directory and sends their content via msmq. The part that iterates
and sends the files is in a separate thread. I have a button on the form
that allows the user to pause or resume the sending of these files. I'm
currently using thread.suspend and thread.resume for this. In the .NET
Framework 2.0 documentation it states that these methods are now deprecated.

How else can I achieve this functionality without using these methods?

Thanks!

The reason Suspend and Resume is deprecated is that you're suspending
the hardware thread, at whatever position it is currently being
executed. If you suspend it inside a lock(){...} block, that lock will
not be released until you resume the thread.

In other words, outside code is able to destabilize your system by
making locks stay longer than necessary.

By using events like the others suggested you yourself adds the points
where your thread is safe to be "suspended". For instance, what if the
code that talks to MSMQ is suspended in the middle? Will MSMQ time out
after a while and when you resume the thread it might not be able to
complete the current transaction? Such things is why they have become
deprecated.
 

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