Re[3]: инициализация поля класса и события
От: HowardLovekraft  
Дата: 21.09.12 10:32
Оценка: +2
Здравствуйте, kandev, Вы писали:

K>так что вариант что код добавляется в начало конструктора маловероятен.

Рукалицо. Добавляется. В начало.

Однако, разница между:
public partial class Form1 : Form
{
    Barcode barc = new Barcode();

    public Form1()
    {
        InitializeComponent();
            
        barc.Initialise("COM42");
    }
}

и
public partial class Form1 : Form
{
    public Form1()
    {
        barc = new Barcode();

        InitializeComponent();
            
        barc.Initialise("COM42");
    }
}

к сожалению, есть. И эта разница в моменте вызова конструктора базового класса.

В первом случае, в коде конструктора сначала будет проинициализировано поле barc, затем будет вызван конструктор базового класса.
Во втором случае, сначала будет вызван конструктор базового класса, затем проинициализировано поле barc.
Re[4]: инициализация поля класса и события
От: HowardLovekraft  
Дата: 21.09.12 09:53
Оценка: +1
Здравствуйте, Sshur, Вы писали:

S>Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора.

Блджад. Да где ж вы такую траву забористую берете?
    class MyClass
    {
        int i = 10;

        public MyClass()
        {
        }
    }


.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   10
  IL_0003:  stfld      int32 ConsoleApplication1.MyClass::i
  IL_0008:  ldarg.0
  IL_0009:  call       instance void [mscorlib]System.Object::.ctor()
  IL_000e:  ret
} // end of method MyClass::.ctor
инициализация поля класса и события
От: kandev  
Дата: 21.09.12 08:23
Оценка:
есть два варианта инициализации переменной barc — первый сразу при объявлении
второй в конструкторе.

1.
    public partial class Form1 : Form
    {

        Barcode barc = new Barcode();

        public Form1()
        {
            InitializeComponent();
            
            barc.Initialise("COM42");

        }


2.
    public partial class Form1 : Form
    {


        Barcode barc = null;

        public Form1()
        {
            InitializeComponent();
            
            barc = new Barcode();

            barc.Initialise("COM42");

        }


и в первом и во втором случае переменная barc инициализируется и работает, но к сожалению по-разному.

в функции Initialise будут добавляться обработчики событий:

                mySystem.DmccResponseArrived += new Cognex.DataMan.SDK.DataManSystem.DmccResponseArrivedEventHandler(this.mySystem_DmccResponseArrived);
                mySystem.ImageArrived += new Cognex.DataMan.SDK.DataManSystem.ImageArrivedEventHandler(this.mySystem_ImageArrived);


теперь по существу:
в первом случае события которые добавляются к mySystem НЕ происходят,
а во втором случае инициализации события происходят!

в чём разница?
events eventhandler
Re: инициализация поля класса и события
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 21.09.12 08:26
Оценка:
Здравствуйте, kandev, Вы писали:
K>теперь по существу:
K>в первом случае события которые добавляются к mySystem НЕ происходят,
K>а во втором случае инициализации события происходят!

K>в чём разница?


Ну, единственная разница, которую я вижу — это то, что в первом случае barc = new Barcode(); выполняется до InitializeComponent, а во втором случае после.
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re: инициализация поля класса и события
От: Nikolay_Ch Россия  
Дата: 21.09.12 08:31
Оценка:
Здравствуйте, kandev, Вы писали:

K>в чём разница?

ИМХО, при инициализации прямо в коде, код этой инициализации добавляется в начало каждого конструктора, а не в его конец.
Re[2]: инициализация поля класса и события
От: kandev  
Дата: 21.09.12 08:37
Оценка:
даже если я перемещу до InitialiseComponent — всё работает и события происходят — баркод читается.
так что вариант что код добавляется в начало конструктора маловероятен.

 public Form1()
        {
            barc = new Barcode();

            InitializeComponent();
            

            barc.Initialise("COM42");


K>>в чём разница?

N_C>ИМХО, при инициализации прямо в коде, код этой инициализации добавляется в начало каждого конструктора, а не в его конец.
Re[2]: инициализация поля класса и события
От: kandev  
Дата: 21.09.12 08:46
Оценка:
похоже что не только до InitializeComponent, а еще до чего-то.
если в конструкторе инициализировать переменную barc до InitializeComponent, то всё работает и события происходят!


Здравствуйте, Sshur, Вы писали:
S>Ну, единственная разница, которую я вижу — это то, что в первом случае barc = new Barcode(); выполняется до InitializeComponent, а во втором случае после.
Re[3]: инициализация поля класса и события
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 21.09.12 08:52
Оценка:
Здравствуйте, kandev, Вы писали:

K>похоже что не только до InitializeComponent, а еще до чего-то.

K>если в конструкторе инициализировать переменную barc до InitializeComponent, то всё работает и события происходят!

Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора. Возможно, у вас из-за этого вылезают какие-то побочные эффекты.

Откуда берется объект mySystem? может в первом случае он не существует до того, как создастся объект barcode. Надо смотреть ваш код


Если вы поставите точку останова на new Form1 (), то по F11 вы сначала пройдете по всем инициализаторам, а потом по конструктору Form1(). Можно будет разобраться, что там не так
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[4]: инициализация поля класса и события
От: kandev  
Дата: 21.09.12 09:13
Оценка:
Здравствуйте, Sshur, Вы писали:

S>Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора. Возможно, у вас из-за этого вылезают какие-то побочные эффекты.


S>Откуда берется объект mySystem? может в первом случае он не существует до того, как создастся объект barcode. Надо смотреть ваш код


S>Если вы поставите точку останова на new Form1 (), то по F11 вы сначала пройдете по всем инициализаторам, а потом по конструктору Form1(). Можно будет разобраться, что там не так


трассировка ничего не даёт. выполняется инициализация barc а дальше InitialiseComponent.


Вот полный код:

следующий этап — COM dll чтобы использовать её в unmanaged MFC приложении.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Cognex.DataMan.SDK;
using Cognex.DataMan.SDK.Events;
using System.Timers;



namespace barcodetest1win
{



    public partial class Form1 : Form
    {


        Barcode barc = null;

        public Form1()
        {
            barc = new Barcode();

            InitializeComponent();
            

            barc.Initialise("COM42");

        }

        private void button1_Click(object sender, EventArgs e)
        {


            string res = barc.GetBarcode(5000);
            label2.Text = res;



        }

        private void button2_Click(object sender, EventArgs e)
        {
            if(!barc.IsInitialised())
                barc.Initialise("COM42");

        }

    }





    public interface CognexDLL
    {
        string Initialise(string comport);
        string GetBarcode(int timeon);
        bool IsInitialised();
        int Close();

    }


    public class Barcode : CognexDLL
    {

        /// <summary>
        /// Provides functionalities needed to work with DataMan devices.
        /// </summary>
        Cognex.DataMan.SDK.DataManSystem mySystem = null;


        System.Timers.Timer tm = null;

        public string resultText;

        public Barcode()
        {
            System.Media.SystemSounds.Beep.Play();
            resultText = "empty";
            mySystem = new Cognex.DataMan.SDK.DataManSystem();
            tm = new System.Timers.Timer();
        }


        void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            System.Media.SystemSounds.Beep.Play();
            resultText = mySystem.TransmittedResults.ToString();
        }


        public string Initialise(string comport)
        {

            string address = comport; //Use: "xxx.xxx.xxx.xxx" (IPv4) or "COMx"

            if (mySystem == null)
            {
                mySystem = new DataManSystem();
            }

            try
            {
                mySystem.Imaging.Live.Enabled = false;
            }
            catch (Exception e3)
            {
                //MessageBox.Show(e3.Message);
            }



            try
            {
                mySystem.Connect(new DataManConnectionParams(address));
            }
            catch (Exception eConnect)
            {
                //MessageBox.Show(eConnect.Message);
            }

            //If connected
            if (mySystem.IsConnected())
            {


                System.Media.SystemSounds.Beep.Play();
                mySystem.DmccResponseArrived += new Cognex.DataMan.SDK.DataManSystem.DmccResponseArrivedEventHandler(this.mySystem_DmccResponseArrived);
                mySystem.ImageArrived += new Cognex.DataMan.SDK.DataManSystem.ImageArrivedEventHandler(this.mySystem_ImageArrived);
                mySystem.GraphicArrived += new Cognex.DataMan.SDK.DataManSystem.GraphicArrivedEventHandler(this.mySystem_GraphicArrived);
                mySystem.ResultArrived += new Cognex.DataMan.SDK.DataManSystem.ResultArrivedEventHandler(this.mySystem_ResultArrived);
                mySystem.HeartBeatSkipped += new EventHandler(mySystem_HeartBeatSkipped);

                //mySystem.DmccResponseArrived += delegate { Console.WriteLine("hello world"); };


                tm.Interval = 3000;
                //tm.Enabled = true;
                //tm.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimedEvent);
                // tm.Start();
                //Timer event works!!!



                return comport + "Initialised.";


            }

            return "failed";
        }

        /// <summary>
        /// Displaying responses to DMCC commands.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void mySystem_DmccResponseArrived(object sender, DmccResponseArrivedEventArgs e)
        {
            System.Media.SystemSounds.Beep.Play();
            //Response arrived - To which sent command?
            if (e.Data != null)
            {
                resultText = e.Data;
            }

            

        }


        public void mySystem_ResultArrived(object sender, ResultArrivedEventArgs e)
        {

            System.Media.SystemSounds.Beep.Play();
            if (e.Result != null)
            {
                resultText = e.Result;
            }
        }

        void mySystem_ImageArrived(object sender, ImageArrivedEventArgs e)
        {
            System.Media.SystemSounds.Beep.Play();
        }

        void mySystem_GraphicArrived(object sender, GraphicArrivedEventArgs e)
        {
            System.Media.SystemSounds.Beep.Play();
        }

        void mySystem_HeartBeatSkipped(object sender, EventArgs e)
        {
            //MessageBox.Show("Heartbeat skipped");
            System.Media.SystemSounds.Beep.Play();
        }

        public bool IsInitialised()
        {
            return mySystem.IsConnected();
        }

        public string GetBarcode(int timeon)
        {
            //code

            mySystem.SendDmcc("||>TRIGGER ON");

            System.Threading.Thread.Sleep(timeon / 10);
            return resultText;
        }

        public int Close()
        {
            return 1;
        }
    }
}
Re[5]: инициализация поля класса и события
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 21.09.12 10:06
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, Sshur, Вы писали:


S>>Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора.

HL>Блджад. Да где ж вы такую траву забористую берете?

Получается, да. Никогда не обращал внимания что до попадания в тело конструктора отладчик в него таки попадает
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[4]: инициализация поля класса и события
От: Nikolay_Ch Россия  
Дата: 21.09.12 10:37
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>В первом случае, в коде конструктора сначала будет проинициализировано поле barc, затем будет вызван конструктор базового класса.

HL>Во втором случае, сначала будет вызван конструктор базового класса, затем проинициализировано поле barc.

А что понимается под конструктором базового класса?
Re[4]: инициализация поля класса и события
От: Sinix  
Дата: 21.09.12 10:38
Оценка:
Здравствуйте, Sshur, Вы писали:


S>Ну, это факт, что инициализаторы полей класса выполняются до конструктора.


До вызова базового
Автор: Sinix
Дата: 31.08.12
конструктора. Скорее всего, Barcode завязан на побочные эффекты конструктора Control(). В последнем как минимум задаётся текущий SynchronizationContext (если не задан ранее).
Re[4]: инициализация поля класса и события
От: HowardLovekraft  
Дата: 21.09.12 10:39
Оценка:
Для:
    class A
    {
        public void Foo() {}
    }

    class B
    {
        A a = new A();

        public B()
        {
            Bar();
            a.Foo();
        }

        private void Bar() {}
    }

На выходе получим вот это:
.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       35 (0x23)
  .maxstack  8
  IL_0000:  ldarg.0

  IL_0001:  newobj     instance void ConsoleApplication1.A::.ctor()
  IL_0006:  stfld      class ConsoleApplication1.A ConsoleApplication1.B::a
  IL_000b:  ldarg.0
  IL_000c:  call       instance void [mscorlib]System.Object::.ctor()

  IL_0011:  ldarg.0
  IL_0012:  call       instance void ConsoleApplication1.B::Bar()
  IL_0017:  ldarg.0
  IL_0018:  ldfld      class ConsoleApplication1.A ConsoleApplication1.B::a
  IL_001d:  callvirt   instance void ConsoleApplication1.A::Foo()
  IL_0022:  ret
} // end of method B::.ctor


А для:
    class A
    {
        public void Foo() {}
    }

    class B
    {
        A a;

        public B()
        {
            a = new A();
            Bar();
            a.Foo();
        }

        private void Bar() {}
    }

это:
.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       35 (0x23)
  .maxstack  8

  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ldarg.0
  IL_0007:  newobj     instance void ConsoleApplication1.A::.ctor()
  IL_000c:  stfld      class ConsoleApplication1.A ConsoleApplication1.B::a

  IL_0011:  ldarg.0
  IL_0012:  call       instance void ConsoleApplication1.B::Bar()
  IL_0017:  ldarg.0
  IL_0018:  ldfld      class ConsoleApplication1.A ConsoleApplication1.B::a
  IL_001d:  callvirt   instance void ConsoleApplication1.A::Foo()
  IL_0022:  ret
} // end of method B::.ctor
Re[5]: инициализация поля класса и события
От: Nikolay_Ch Россия  
Дата: 21.09.12 10:50
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

А можно для сидящих в танке? Насколько я понимаю у топикастера метод InitializeComponent производит инициализацию событий. Здесь-то откуда разница берется?
Re[5]: инициализация поля класса и события
От: Doc Россия http://andrey.moveax.ru
Дата: 21.09.12 10:59
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>А что понимается под конструктором базового класса?


Именно он. Конструктор, заданный в базовом типе. Вот — держите, играйтесь на здоровье

namespace ConsoleApplication1
{
    using System;

    internal class A
    {
        public A()
        {
            Console.WriteLine("ctor A");
        }
    }

    internal class B1
    {
        public B1()
        {
            Console.WriteLine("ctor B1");
        }
    }

    internal class B2
    {
        public B2()
        {
            Console.WriteLine("ctor B2");
        }
    }

    internal class C : A
    {
        private B1 _b1 = new B1();

        public C()
        {
            Console.WriteLine("ctor C");
            var b2 = new B2();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();

            Console.ReadKey(true);
        }
    }

}
Re[5]: инициализация поля класса и события
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 21.09.12 10:59
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

А еще, конструкторы полей позовутся перед вторым конструктором в таком случае
    class A
    {
        public void Foo() {}
    }

    class B
    {
        A a = new A();

        public B():this(false){  }

        public B(bool param)
        {
            Bar(param);
            a.Foo();
        }

        private void Bar() {}
    }


А так должен быть Null ref:
    class A
    {
        public void Foo() {}
    }

    class B
    {
        A a ;

        public B():this(false){ 
            a = new A();
        }

        public B(bool param)
        {
            Bar(param);
            a.Foo();
        }

        private void Bar() {}
    }


в этом плане, this не отличается от base. Так?
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[6]: инициализация поля класса и события
От: Nikolay_Ch Россия  
Дата: 21.09.12 12:14
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, Nikolay_Ch, Вы писали:


N_C>>А что понимается под конструктором базового класса?


Doc>Именно он. Конструктор, заданный в базовом типе. Вот — держите, играйтесь на здоровье

Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?
Re[7]: инициализация поля класса и события
От: kandev  
Дата: 21.09.12 12:28
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?



проблема кроется где-то между инициализацией полей класса и конструктором.
причем если в классе Barcode создать таймер и на него повесить событие, то все работает, не работает mySystem.
mySystem обслуживает ком порт, и не приходят ответы от компорта.
Re[8]: инициализация поля класса и события
От: Sinix  
Дата: 21.09.12 12:41
Оценка:
Здравствуйте, kandev, Вы писали:

K>проблема кроется где-то между инициализацией полей класса и конструктором.

Уже отвечал Barcode (точнее, DataManSystem) где-то завязан на побочные эффекты конструктора Control() (скорее всего на контекст синхронизации, задаваемый при первом создании контрола в текузем потоке). Если не создавать mySystem до вызова Initialise — поможет?
Re[9]: инициализация поля класса и события
От: kandev  
Дата: 21.09.12 13:06
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, kandev, Вы писали:


K>>проблема кроется где-то между инициализацией полей класса и конструктором.

S>Уже отвечал Barcode (точнее, DataManSystem) где-то завязан на побочные эффекты конструктора Control() (скорее всего на контекст синхронизации, задаваемый при первом создании контрола в текузем потоке). Если не создавать mySystem до вызова Initialise — поможет?

похоже что так, но как это сделать?

кстати — если написать так — то все работает, баркоды приходят.

    public partial class Form1 : Form
    {


        Barcode barc = new Barcode();

        public Form1()
        {
              
            barc = new Barcode();        


            InitializeComponent();
            
            
           
            barc.Initialise("COM42");

        }
Re[7]: инициализация поля класса и события
От: Doc Россия http://andrey.moveax.ru
Дата: 21.09.12 13:32
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?


Поглядите на родителей Form — там порядком глубина наследования. Собственно вот о том же говорят http://www.rsdn.ru/forum/dotnet/4900914.1
Автор: Sinix
Дата: 21.09.12
Re[10]: инициализация поля класса и события
От: Doc Россия http://andrey.moveax.ru
Дата: 21.09.12 13:34
Оценка:
Здравствуйте, kandev, Вы писали:

K>кстати — если написать так — то все работает, баркоды приходят.


Конечно, т.к. будет создан новый экземпляр barc = new Barcode();, а тот что в инициализации поля Barcode barc = new Barcode(); станет мусором.
Re[10]: инициализация поля класса и события
От: Sinix  
Дата: 21.09.12 13:43
Оценка:
Здравствуйте, kandev, Вы писали:

K>похоже что так, но как это сделать?

У вас mySystem всё равно создастся в Initialise(), так что достаточно
        public Barcode()
        {
            System.Media.SystemSounds.Beep.Play();
            resultText = "empty";
            // mySystem = new Cognex.DataMan.SDK.DataManSystem();
            tm = new System.Timers.Timer();
        }


K>кстати — если написать так — то все работает, баркоды приходят.

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