如何同步这些线程以避免数据损坏?

时间:2009-02-16 15:43:36

标签: c# multithreading

TL; DR版:我有两个帖子。其中一个可能需要Interrupt()另一个,但只有当另一个线程处于与受第一个线程影响的对象相关的数据处理中间时。我怎样才能根据某些条件中断()第二个线程。

我一直致力于一个程序,该程序可以旋转两个线程来处理套接字数据并使用这些信息更新GUI。两个线程(topologyThread和dataThread)处理我的应用程序的两个不同方面,即我们的无线传感器网络的拓扑更改通知,以及用于从无线传感器网络接收和处理数据的数据信息。

当数据进入dataThread时,数据包所代表的网络成员可能已被topologyThread删除,因此不应处理。所以,我认为使用Thread.Interrupt()方法可以让我立即通知dataThread拓扑的变化,并防止我们在尝试使用网络成员的数据更新GUI时遇到的一些问题。不再连接。我的问题是:如何判断dataThread是否需要中断?我不希望它在处理仍然连接的网络成员的数据时抛出异常,但是如果它正在处理网络成员的数据然后断开连接,我希望它被中断。

情景1:

  • 数据来自dataThread。
  • dataThread确保网络成员仍然是网络的一部分。
  • dataThread将数据处理到最后并更新GUI

情景2:

  • 数据来自dataThread。
  • dataThread确保网络成员仍然是网络的一部分。
  • 网络成员已断开连接,因此无法进行处理。

情景3:

  • 数据来自dataThread。
  • dataThread确保网络成员仍然是网络的一部分。
  • dataThread开始处理数据
  • topologyThread会收到网络成员断开连接的通知,并将其从拓扑中删除。
  • dataThread尝试更新不再连接的网络成员的GUI。

我正在尝试编写的方案3。在我们的测试中,这种情况是侧边栏中的树视图冻结,应用程序必须被杀死。但是,如果受拓扑线程影响的对象是dataThread当前正在处理的对象,我只需要中断dataThread。

感谢阅读。 :)

4 个答案:

答案 0 :(得分:2)

你不应该打断你的线程。使用EventWaitHandles对这些进行编程可能会更安全,因为EventWaitHandles可以根据你想要实现的目标来发出信号。

答案 1 :(得分:1)

  

dataThread尝试更新不再连接的网络成员的GUI。

如果在网络成员不再连接时有topologyThread设置了一个标志,并且在尝试更新GUI之前让dataThread检查该标志怎么办?

答案 2 :(得分:0)

Interrupt()仅在线程被阻止时才有效...所以你需要有另一种机制来停止处理。如果你有一个处理数据的循环,最好的方法是有一个变量,如果它被设置就会终止处理。

我会怎么做......

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();
    }
}

答案 3 :(得分:0)

基本版。增强以满足您的需求。

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.
        }
    }
}