[ bigguy @ 05.08.2010. 08:58 ] @
Imam ovu klasu:
Code (csharp):

     public class Semaphore
     {
          private Mutex[] m_mutex;
          private Thread[] m_threadIds;
          private int m_threadLimit;

          // constructor
          // parameter - threadLimit (number of threads to control)
          public Semaphore(int threadLimit)
          {
               m_threadLimit = threadLimit;
               m_mutex = new Mutex[m_threadLimit];
               m_threadIds = new Thread[m_threadLimit];
               for (int i=0; i<m_threadLimit; i++)
               {
                    m_mutex[i] = new Mutex();
                    m_threadIds[i] = null;
               }
          }

          // if there is a timeout then WaitHandle.WaitTimeout is returned
          // calling thread should check for this
          public int Wait()
          {
               int index = WaitHandle.WaitAny(m_mutex);
               if (index != WaitHandle.WaitTimeout)
                    m_threadIds[index] = Thread.CurrentThread;
               return index;
          }

          // release the mutex locked by the thread
          public void Release()
          {
               for (int i=0; i<m_threadLimit; i++)
               {
                    if (m_threadIds[i] == Thread.CurrentThread)
                    {
                         m_mutex[i].ReleaseMutex();
                    }
               }
          }

     }
 


i imam ovaj kod u MainForm:
Code (csharp):

        public const byte ENQ = 0x05;
        public static byte[] ENQ_BUFF = { ENQ };

        private void btnSend_Click(object sender, EventArgs e)
        {
            Thread s = new Thread(new ParameterizedThreadStart(SendX));
            s.Start(ENQ_BUFF);
        }

        private void SendX(object param)
        {
            m_semaphore.Wait();
            byte[] msg = (byte[])param;
            Send(msg);
            frmDataSend new_frmDataSend = new frmDataSend();
            new_frmDataSend.Show();
            m_semaphore.Release();
        }

        private void Send(byte[] msg)
        {
            //slanje podataka
        }
 


Moje pitanje je zasto se new_frmDataSend otvori i zatvori odmah? Meni je potrebno da dok god ja new_frmDataSend rucno ne ztvorim da se ona ne gasi. Ono sto je meni potrebno je ono sto se desava kada umesto
Code (csharp):

            frmDataSend new_frmDataSend = new frmDataSend();
            new_frmDataSend.Show();
 

stavim
Code (csharp):

            MessageBox.Show("WORK. JEEE!");
 

Kakava je razlika izmedju MessageBox koji se gasi na OK button i Form koja se gasi na OK button?

[Ovu poruku je menjao mmix dana 05.08.2010. u 10:09 GMT+1]
[ AMD guy @ 05.08.2010. 09:02 ] @
Uradi debug, da vidis gde je greska.
Pa stavi ovde.
[ bigguy @ 05.08.2010. 09:05 ] @
Boze naivnosti...resenje je u tome da ukoliko stoji new_frmDataSend.Show() tada kod zatvara formu ali kada stoji new_frmDataSend.ShowDialog() to se ne desava. Eto sa ovim se patim 2h i nista nisam mogao da uradim dok nisam postavio pitanje :)
Nekada su neke stvari prosto inspirativne ;)
[ AMD guy @ 05.08.2010. 09:10 ] @
I najboljim se desava
[ mmix @ 05.08.2010. 09:11 ] @
Cisto iz kurioziteta, sta radis sa ovim programom. Onaj semaphor class mi deluje preterano zakomplikovan.
[ bigguy @ 05.08.2010. 12:50 ] @
No problem mmix.
Pokusavam da omogucim da svaki put kada korisnik klikne da se podaci posalju on naredbu slanja prihvata bez obzira da li je predhodne podatke vec uspeo da posalje. Kada te prdhodne uspe da posalje onda prihvata sledece koji su dosli na red itd.
Nadam se da sam uspeo da objasnim?!
[ mmix @ 05.08.2010. 13:16 ] @
Ok, asinhrono slanje sa redom, al sta ce ti mutex za svaki thread? Moze to i mnogo jednostavnije, jedan komunikacioni thread (kad vec moras da serijalizujes slanja) i mutex samo za komunikaciju sa tim threadom.

Isto mislim da imas potencijalno opasan problem sto dizes nove forme u threadovima, Winforms nije dizajniran da radi sa multithreaded operacijama, sve elemente treba generisati i odrzavati iz glavnog thread-a (zbog njegovog message queue-a)

[ bigguy @ 05.08.2010. 23:33 ] @
Imas prava sto se tice generisanja formi upravo sam dosao do tog problema, jer formu frmDataSend ne mogu da zatvorim nakon odredjenog dogadjaja. Prijavljuje se Cross-thread problem.
Na osnovu tvoje sugestije formu frmDataSend generisao sam u okviru glavnog threada i samo sam je pokreatao putem ShowDialog() u Thread s. Takodje, kada sam zeleo da pristupim formi kako bi je zatvorio to sam radio putem delegata, ali problem Cross-thread se i dalje ponovlja.
Postojili neka solucija...
[ lukeguy @ 06.08.2010. 07:10 ] @
Sve što želiš da izmeniš u UI niti iz druge niti moraš da radiš pozivajući Invoke().

Na primer, ako tvoja forma ima neki string property koji želiš da promeniš, to radiš ovako:
Code:

private delegate void SetStringDelegate(string value);

private void SetStringProperty(string text)
        {
            if(InvokeRequired)
            {
                Invoke(new SetStringDelegate(SetStringProperty), new Object[] { text });
            }
            else
            {
                StringProperty = text;
            }
        }
[ bigguy @ 06.08.2010. 13:58 ] @
Da li postoji mogucnost da ja frmDataSend generisem na glavnom threadu, da je pokrecem na thread_1, a da je gasim u okviru eventa timer_tick?
[ bigguy @ 06.08.2010. 23:40 ] @
Ovo je resilo stvar
http://www.csharp411.com/close-all-forms-in-a-thread-safe-manner/

[Ovu poruku je menjao bigguy dana 07.08.2010. u 01:41 GMT+1]