У меня проблема с данными, которые, похоже, сбрасываются до значений по умолчанию. Класс выглядит следующим образом (objectIDs - простое перечисление):
public class Output_args: EventArgs {
public objectIDs outputtype;
public int internalID;
public int verdict;
public int outputID;
public long entrytime;
public Output_args Copy() {
Output_args args = new Output_args();
args.entrytime = this.entrytime;
args.internalID = this.internalID;
args.outputID = this.outputID;
args.outputtype = this.outputtype;
args.verdict = this.verdict;
return args;
}
}
Следующий код создает объект. Он работает в определенном потоке, пусть говорит Thread1.
class Class1 {
EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
public event EventHandler<Output_args> newOutput;
public void readInput(){
List<Output_args> newoutputlist = new List<Output_args>();
/*
* code to determine the outputs
*/
Output_args args = new Output_args();
args.outputtype = objectIDs.stepID;
args.internalID = step[s].ID;
args.verdict = verdict;
args.entrytime = System.DateTime.Now.Ticks;
newoutputlist.Add(args.Copy());
if (newOutput != null && newoutputlist.Count > 0) {
// several outputs are being sent sequentially but for simplicity i've removed the for-loop and decision tree
try {
newOutput(null, newoutputlist[0].Copy());
} catch (Exception) { }
}
}
}
1 подписчика на это событие имеет следующий код. Метод процессора работает на потоке camerafeed. Обработчик события newOutput запускается в Thread1.
class Class2: Form {
private Output_args lastoutput = new Output_args();
public void newOutput(object sender, Output_args args) {
lock (lastoutput) {
lastoutput = args.Copy();
}
}
public void processor(){
lock (lastoutput) {
if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
Когда вызывается обработчик событий "newOutput" класса 2, отладчик показывает, что копия работает так, как ожидалось, и "входное время" получает ожидаемое количество тиков.
Однако, когда процессорный метод хочет прочитать "время входа", его значение равно 0. Все остальные поля также имеют назначенное им значение по умолчанию.
Я попытался заменить объект "lastoutput" простым полем типа long и удалил блокировки, но результаты были одинаковыми: он правильно назначается в "newOutput", но имеет значение по умолчанию (0) в методе процессора.
Любые идеи о том, почему это происходит?
вам не следует блокировать объект lastoutput
, но на другом объекте, потому что вы переназначаете это поле.
Процессор запускает и блокирует экземпляр поля по умолчанию new Output_args()
инициализированный значениями по умолчанию
class Class2: Form {
private object mylock = new object();
private Output_args lastoutput;
public void newOutput(object sender, Output_args args) {
lock (mylock) {
lastoutput = args.Copy();
}
}
public void processor(){
lock (mylock) {
if (lastoutput == null) {
//nothing to consume yet
}
else if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
но это отбрасывает lastouput, если потребитель медленнее производителя. Вы можете использовать очередь (или другую коллекцию) в качестве буфера, если это необходимо.
class Class2 {
private Queue<Output_args> outputs = new Queue<Output_args>();
public void newOutput(object sender, Output_args args) {
lock (outputs) {
outputs.Enqueue(args.Copy());
}
}
public void processor(){
lock (outputs) {
if (outputs.Count > 0) {
var lastoutput = outputs.Dequeue();
if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
}