Почему Thread не умирает?
От: Abuserrr  
Дата: 26.07.06 17:40
Оценка:
Есть клиент-серверное приложение. Клиент время от времени посылает сообщения на сервер (сервер их обрабатывает и сохраняет в БД). Для этого был создан класс скажем Server:MarshalByRefObject
в котором собственно идет отсылка сообщения Server.SendToServer().
Далее на клиенте время от времени отсылаються сообщения на сервер:

private static Thread m_SendToServerThread;
private static int m_WaitDelay=1000*60*12; 
private static System.Threading.Timer m_WaitForSend;
public Send(Queue m_Queue)
{
bool isNotSent=true;
while (m_Queue.Count>0)
{

SendArgs argsToSend=m_Queue.Dequeue() as SendArgs;

while (isNotSent)
{
    try
    {                    
        SendToServerClass sts=new SendToServerClass(argsToSend);
        m_SendToServerThread=new Thread(new ThreadStart(sts.SendToServerMethod));
        m_SendToServerThread.Start();
        m_WaitForSend.Change(m_WaitDelay, Timeout.Infinite);
        m_SendToServerThread.Join();
        m_WaitForSend.Change(Timeout.Infinite, Timeout.Infinite);
        m_SendToServerThread=null;
        if (sts.isError && sts.Exception!=null)
        {
            throw sts.Exception;
        }
        if (sts.IsSent)
        {
           isNotSent=false;                        
        } 
    }
    catch (Exception ex)
    {
        Thread.Sleep(12000);//Send failed. Try again in 12 seconds
    }
}

}

}

private static void onWaitTimer(object p_state)
{
    if (m_SendToServerThread!=null && m_SendToServerThread.IsAlive)
    {
            m_SendToServerThread.Abort(); 
        }
}


public class SendToServerClass
{
    private MessageEventArgs m_argsToSend;
    private bool m_isSent;
    private bool m_WasError;
    private Exception m_Exception;
    public bool IsSent
    {
    get { return m_isSent; }
    }

    public bool isError
    {
        get { return m_WasError; }
    }

    public Exception Exception
    {
        get { return m_Exception; }
    }

    public SendToServerClass(MessageEventArgs p_argsToSend)
    {
        m_isSent=false;
        m_WasError=false;
        m_Exception=null;
           m_argsToSend=p_argsToSend;
    }
    public void SendToServerMethod()
    {
        try
        {
            Server.Instance.SendToServer(m_argsToSend);
            m_isSent=true;
        }
        catch (Exception ex)
        {
            m_Exception=ex;
            m_WasError=true;
            m_isSent=false;
        }
    }
}


В большинстве случаев все работает нормально, но где-то раз в три дня интенсивного исспользования m_SendToServerThread подвисает и соответственно остальные сообщения не отсылаються, так как мы ждем отсылки сообщения m_SendToServerThread.Join(); (ждать надо обезатьельно, так как порядок важен). Для решения этой проблемы ввел System.Threading.Timer, но m_SendToServerThread.Abort(); не всегда убивает поток. В тех случаях когда не убивает, поток просто переходит в состояние ThreadState.AbortRequested и никогда из него не выходит Научился воспроизводить это зависание (если клиент и БД находяться на одном компе, а сервер на втором, и в момент отсылки сообщения выключить компьютер с клиентом, то это зависание и происходит, даже если потом востановить соединение), так что тестировать возможно. Сервер не умирает, и до него возможно достучаться с клиента. Вопрос в том, как убить этот поток, чтоб не происходило этого зависания.

з.ы. Извиняюсь за такой обьемный вопрос, просто никак не могу решить эту проблему
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.