Здравствуйте, 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.
Здравствуйте, 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.0IL_0001: ldc.i4.s 10IL_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
есть два варианта инициализации переменной 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 НЕ происходят,
а во втором случае инициализации события происходят!
Здравствуйте, kandev, Вы писали: K>теперь по существу: K>в первом случае события которые добавляются к mySystem НЕ происходят, K>а во втором случае инициализации события происходят!
K>в чём разница?
Ну, единственная разница, которую я вижу — это то, что в первом случае barc = new Barcode(); выполняется до InitializeComponent, а во втором случае после.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, kandev, Вы писали:
K>в чём разница?
ИМХО, при инициализации прямо в коде, код этой инициализации добавляется в начало каждого конструктора, а не в его конец.
даже если я перемещу до InitialiseComponent — всё работает и события происходят — баркод читается.
так что вариант что код добавляется в начало конструктора маловероятен.
public Form1()
{
barc = new Barcode();
InitializeComponent();
barc.Initialise("COM42");
K>>в чём разница? N_C>ИМХО, при инициализации прямо в коде, код этой инициализации добавляется в начало каждого конструктора, а не в его конец.
похоже что не только до InitializeComponent, а еще до чего-то.
если в конструкторе инициализировать переменную barc до InitializeComponent, то всё работает и события происходят!
Здравствуйте, Sshur, Вы писали: S>Ну, единственная разница, которую я вижу — это то, что в первом случае barc = new Barcode(); выполняется до InitializeComponent, а во втором случае после.
Здравствуйте, kandev, Вы писали:
K>похоже что не только до InitializeComponent, а еще до чего-то. K>если в конструкторе инициализировать переменную barc до InitializeComponent, то всё работает и события происходят!
Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора. Возможно, у вас из-за этого вылезают какие-то побочные эффекты.
Откуда берется объект mySystem? может в первом случае он не существует до того, как создастся объект barcode. Надо смотреть ваш код
Если вы поставите точку останова на new Form1 (), то по F11 вы сначала пройдете по всем инициализаторам, а потом по конструктору Form1(). Можно будет разобраться, что там не так
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, 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;
}
}
}
Здравствуйте, HowardLovekraft, Вы писали:
HL>Здравствуйте, Sshur, Вы писали:
S>>Ну, это факт, что инициализаторы полей класса выполняются до конструктора. Не в начале конструктора, а до конструктора. HL>Блджад. Да где ж вы такую траву забористую берете?
Получается, да. Никогда не обращал внимания что до попадания в тело конструктора отладчик в него таки попадает
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, HowardLovekraft, Вы писали:
HL>В первом случае, в коде конструктора сначала будет проинициализировано поле barc, затем будет вызван конструктор базового класса. HL>Во втором случае, сначала будет вызван конструктор базового класса, затем проинициализировано поле barc.
А что понимается под конструктором базового класса?
конструктора. Скорее всего, Barcode завязан на побочные эффекты конструктора Control(). В последнем как минимум задаётся текущий SynchronizationContext (если не задан ранее).
А можно для сидящих в танке? Насколько я понимаю у топикастера метод InitializeComponent производит инициализацию событий. Здесь-то откуда разница берется?
Здравствуйте, 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);
}
}
}
А еще, конструкторы полей позовутся перед вторым конструктором в таком случае
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. Так?
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Doc, Вы писали:
Doc>Здравствуйте, Nikolay_Ch, Вы писали:
N_C>>А что понимается под конструктором базового класса?
Doc>Именно он. Конструктор, заданный в базовом типе. Вот — держите, играйтесь на здоровье
Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?
Здравствуйте, Nikolay_Ch, Вы писали:
N_C>Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?
проблема кроется где-то между инициализацией полей класса и конструктором.
причем если в классе Barcode создать таймер и на него повесить событие, то все работает, не работает mySystem.
mySystem обслуживает ком порт, и не приходят ответы от компорта.
Здравствуйте, kandev, Вы писали:
K>проблема кроется где-то между инициализацией полей класса и конструктором.
Уже отвечал Barcode (точнее, DataManSystem) где-то завязан на побочные эффекты конструктора Control() (скорее всего на контекст синхронизации, задаваемый при первом создании контрола в текузем потоке). Если не создавать mySystem до вызова Initialise — поможет?
Здравствуйте, 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");
}
Здравствуйте, Nikolay_Ch, Вы писали:
N_C>Ну это понятно... Но у топикастера то ситуация иная, по-моему. У него же не вызывается базовый конструктор, у него вызывается метод InitializeControl. Как здесь быть?
Здравствуйте, 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 вместе со своими ошибками в качестве наглядного пособия пожирается сборщиком мусора и больше не участвует в празднике жизни. Спарта-стиль, уважаю