views:

270

answers:

4

TL;DR version: I have two threads. One of them might need to Interrupt() the other, but only if the other thread is in th middle of processing data that is related to the object that is affected by the first thread. How can I only Interrupt() the second thread based on certain conditions.

I have been working on a program that spins up two threads for processing socket data and updating the GUI with the information. The two threads (topologyThread and dataThread) handle two different aspects of my application, namely topology change notifications for our wireless sensor network, and data information for receiving and processing data from the wireless sensor network.

When data is coming into the dataThread, it's possible that the network member that the data packet represents has already been removed by the topologyThread and as such should not be processed. So, I was thinking that using the Thread.Interrupt() method would allow me to instantly notify the dataThread of changes to the topology and prevent some of the problems we have seen with trying to update the GUI with data for a network member that is no longer connected. My question is this: How can I tell if the dataThread needs to be interrupted? I don't want it to throw an exception while it's processing data for a network member that is still connected, but I want it to be interrupted if it's in the middle of processing data for a network member that is then disconnected.

Scenario 1:

  • Data comes in on dataThread.
  • dataThread makes sure network member is still part of the network.
  • dataThread processes data to the end and updates GUI

Scenario 2:

  • Data comes in on dataThread.
  • dataThread makes sure network member is still part of the network.
  • Network member has been disconnected so no processing takes place.

Scenario 3:

  • Data comes in on dataThread.
  • dataThread makes sure network member is still part of the network.
  • dataThread begins processing data
  • topologyThread receives notice that the network member is disconnected and removes it from topology.
  • dataThread tries to update GUI for a network member that is no longer connected.

It's scenario 3 that I am trying to code for. In our testing, this scenario is where the tree view in the sidebar freezes up and the app has to be killed. But I only need to interrupt the dataThread if the object that is affected by the topologyThread is the one that the dataThread is currently acting on.

Thanks for reading. :)

+2  A: 

You shouldn't be interrupting your threads. It might be safer to program these using EventWaitHandles that could fire signals based around what you're trying to achieve instead.

Nicholas Mancuso
EventWaitHandles would only be useful if he the thread he was trying to stop wasn't doing anything. What if it is blocked waiting to read from a network socket? Interrupt() would be appropriate here.
bobwienholt
A: 

Interrupt() only works if the thread is blocked... so you need to have another mechanism to stop processing. If you have a loop that is processing the data, the best way is to have a variable that will kill processing if it is set.

Here's how I would do it...

Thread dataThread;
bool continueProcessing = true;
String currentNetworkMember = "";

public NotifyMemberRemoved(String member)
{
   if (currentNetworkMember == member)
   {
         continueProcessing = false;
         // Incase the thread is blocked...
         dataThread.Interrupt();
   }
}

public void ProcessingLoop()
{
    while (true)
    {
        currentNetworkMember = GetMemberToProcess();
        continueProcessing = true;
        while (continueProcessing)
        {
            try 
            {
               // Process data...
               ReadDataChunk();
               ProcessDataChunk();
            }
            catch (InterruptedException e)
            {
               // Whatever interrupted us must have set continueProcessing to false...
            }
        }
        UpdateGUI();
    }
}
bobwienholt
+1  A: 

dataThread tries to update GUI for a network member that is no longer connected.

What if you have topologyThread set a flag when the network member is no longer connected, and have dataThread check that flag before attempting to update the GUI?

mbeckish
I went with a similar solution to this. If the dataThread is processing a particular network member when the topologyThread tries to remove it, the topologyThread waits until the flag is null before removing it from the topology.
jxpx777
A: 

Basic version. Enhance to suit your needs.

public class CancellationInfo {
    bool _Cancel = false;
    bool _Sync = new object();
    public bool Requested { get { lock(_Sync) { return _Cancel; } }
    public void Request() { lock(_Sync) _Cancel = true; }
}

public class ThreadActions {
    private CancellationInfo Cancel = new CancellationInfo;
    public void FirstThreadAction() {
        while(true) {
            //Process some stuff.
            if(condition)
               Cancel.Request();
        }
    }
    public SecondThreadAction() {
        while(true) {
            if(Cancel.Requested)
                break;
            //Process some stuff.
        }
    }
}
Justice