source: branches/Hive_Management_Console_Refactoring_Ticket508/HeuristicLab.Hive.Server.Console/HiveServerManagementConsole.cs @ 1372

Last change on this file since 1372 was 1372, checked in by aleitner, 11 years ago

find changes in backgroundworker (#508)

File size: 23.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Data;
26using System.Drawing;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.Hive.Contracts.Interfaces;
31using HeuristicLab.Hive.Contracts.BusinessObjects;
32using HeuristicLab.Hive.Contracts;
33
34namespace HeuristicLab.Hive.Server.ServerConsole {
35
36  public delegate void closeForm(bool cf, bool error);
37
38  public partial class HiveServerManagementConsole : Form {
39
40    public event closeForm closeFormEvent;
41
42    #region private variables
43    private ResponseList<ClientGroup> clients = null;
44    private ResponseList<ClientInfo> clientInfo = null;
45    private ResponseList<Job> jobs = null;
46    private ResponseList<UserGroup> userGroups = null;
47    private ResponseList<User> usersList = null;
48
49    private Dictionary<long, ListViewGroup> clientObjects;
50    private Dictionary<long, ListViewItem> clientInfoObjects;
51    private Dictionary<long, ListViewItem> jobObjects;
52    private Dictionary<long, ListViewGroup> userGroupsObjects;
53    private Dictionary<long, ListViewItem> userListObjects;
54
55    private Job currentJob = null;
56    private ClientInfo currentClient = null;
57    private User currentUser = null;
58    private string nameCurrentJob = "";
59    private string nameCurrentClient = "";
60    private string nameCurrentUser = "";
61    private bool flagJob = false;
62    private bool flagClient = false;
63    private bool flagUser = false;
64
65    private List<Changes> changes = new List<Changes>();
66
67    private ToolTip tt = new ToolTip();
68    #endregion
69
70    public HiveServerManagementConsole() {
71      InitializeComponent();
72      AddClients();
73      AddJobs();
74      AddUsers();
75      timerSyncronize.Start();
76    }
77
78    /// <summary>
79    /// event on Ticker
80    /// </summary>
81    /// <param name="obj"></param>
82    /// <param name="e"></param>
83    private void TickSync(object obj, EventArgs e) {
84      //Refresh();
85      if (!updaterWoker.IsBusy) {
86        updaterWoker.RunWorkerAsync();
87      }
88    }
89
90    /// <summary>
91    /// Adds clients to ListView and TreeView
92    /// </summary>
93    private void AddClients() {
94      try {
95        clientObjects = new Dictionary<long, ListViewGroup>();
96        clientInfoObjects = new Dictionary<long, ListViewItem>();
97        IClientManager clientManager =
98          ServiceLocator.GetClientManager();
99
100        clients = clientManager.GetAllClientGroups();
101        lvClientControl.Items.Clear();
102        tvClientControl.Nodes.Clear();
103        int count = 0;
104        foreach (ClientGroup cg in clients.List) {
105          tvClientControl.Nodes.Add(cg.Name);
106          ListViewGroup lvg = new ListViewGroup(cg.Name, HorizontalAlignment.Left);
107          foreach (ClientInfo ci in clientManager.GetAllClients().List) {
108            tvClientControl.Nodes[tvClientControl.Nodes.Count - 1].Nodes.Add(ci.Name);
109            ListViewItem item = new ListViewItem(ci.Name, count, lvg);
110            lvClientControl.Items.Add(item);
111            clientInfoObjects.Add(ci.Id, item);
112            count = (count + 1) % 3;
113          }
114          lvClientControl.BeginUpdate();
115          lvClientControl.Groups.Add(lvg);
116          lvClientControl.EndUpdate();
117          clientObjects.Add(cg.Id, lvg);
118        } // Groups
119
120        clientInfo = clientManager.GetAllClients();
121        ListViewGroup lvunsorted = new ListViewGroup("unsorted", HorizontalAlignment.Left);
122        foreach (ClientInfo ci in clientInfo.List) {
123          tvClientControl.Nodes.Add(ci.Name);
124          lvClientControl.Items.Add(new ListViewItem(ci.Name, count, lvunsorted));
125          count = (count + 1) % 3;
126        }
127        lvClientControl.BeginUpdate();
128        lvClientControl.Groups.Add(lvunsorted);
129        lvClientControl.EndUpdate();
130        if (flagClient) {
131          ClientClicked();
132        }
133      }
134      catch (Exception ex) {
135        closeFormEvent(true, true);
136        this.Close();
137      }
138    }
139
140    /// <summary>
141    /// Adds jobs to ListView and TreeView
142    /// </summary>
143    private void AddJobs() {
144      try {
145        jobObjects = new Dictionary<long, ListViewItem>();
146        IJobManager jobManager =
147          ServiceLocator.GetJobManager();
148        jobs = jobManager.GetAllJobs();
149
150        lvJobControl.Items.Clear();
151        tvJobControl.Nodes.Clear();
152
153        ListViewGroup lvJobCalculating = new ListViewGroup("calculating", HorizontalAlignment.Left);
154        ListViewGroup lvJobFinished = new ListViewGroup("finished", HorizontalAlignment.Left);
155        ListViewGroup lvJobPending = new ListViewGroup("pending", HorizontalAlignment.Left);
156        tvJobControl.Nodes.Add("calculating");
157        tvJobControl.Nodes.Add("finished");
158        tvJobControl.Nodes.Add("pending");
159        foreach (Job job in jobs.List) {
160          if (job.State == State.calculating) {
161            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobCalculating);
162            jobObjects.Add(job.Id, lvi);
163            tvJobControl.Nodes[0].Nodes.Add(job.Id.ToString());
164
165            //lvJobControl.Items.Add(lvi);
166           
167            lvi.ToolTipText = (job.Percentage * 100) + "% of job calculated";
168          } else if (job.State == State.finished) {
169            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobFinished);
170            jobObjects.Add(job.Id, lvi);
171            tvJobControl.Nodes[1].Nodes.Add(job.Id.ToString());
172            //lvJobControl.Items.Add(lvi);
173          } else if (job.State == State.offline) {
174            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobPending);
175            jobObjects.Add(job.Id, lvi);
176            tvJobControl.Nodes[2].Nodes.Add(job.Id.ToString());
177            //lvJobControl.Items.Add(lvi);
178          }
179        } // Jobs
180        lvJobControl.BeginUpdate();
181        foreach (ListViewItem lvi in jobObjects.Values) {
182          lvJobControl.Items.Add(lvi);
183        }
184        lvJobControl.Groups.Add(lvJobCalculating);
185        lvJobControl.Groups.Add(lvJobFinished);
186        lvJobControl.Groups.Add(lvJobPending);
187        lvJobControl.EndUpdate();
188        if (flagJob) {
189          JobClicked();
190        }
191      }
192      catch (Exception ex) {
193        closeFormEvent(true, true);
194        this.Close();
195      }
196    }
197
198    /// <summary>
199    /// Adds users to ListView and TreeView
200    /// </summary>
201    private void AddUsers() {
202      try {
203        userGroupsObjects = new Dictionary<long, ListViewGroup>();
204        userListObjects = new Dictionary<long, ListViewItem>();
205        IUserRoleManager userRoleManager =
206          ServiceLocator.GetUserRoleManager();
207
208        userGroups = userRoleManager.GetAllUserGroups();
209
210        lvUserControl.Items.Clear();
211        tvUserControl.Nodes.Clear();
212
213        foreach (UserGroup ug in userGroups.List) {
214          tvUserControl.Nodes.Add(ug.Name);
215          ListViewGroup lvg = new ListViewGroup(ug.Name, HorizontalAlignment.Left);
216
217          foreach (PermissionOwner permOwner in ug.Members) {
218            if (permOwner is User) {
219              User users = permOwner as User;
220              tvUserControl.Nodes[tvUserControl.Nodes.Count - 1].Nodes.Add(users.Name);
221              ListViewItem item = new ListViewItem(users.Name, 0, lvg);
222              lvUserControl.Items.Add(item);
223              userListObjects.Add(users.Id, item);
224            }
225          }
226          lvUserControl.Groups.Add(lvg);
227          userGroupsObjects.Add(ug.Id, lvg);
228
229        } // Users
230        usersList = userRoleManager.GetAllUsers();
231        ListViewGroup lvunsorted = new ListViewGroup("unsorted", HorizontalAlignment.Left);
232        foreach (User u in usersList.List) {
233          tvUserControl.Nodes.Add(u.Name);
234          lvUserControl.Items.Add(new ListViewItem(u.Name, 0, lvunsorted));
235        }
236        lvUserControl.BeginUpdate();
237        lvUserControl.Groups.Add(lvunsorted);
238        lvUserControl.EndUpdate();
239        if (flagUser) {
240          UserClicked();
241        }
242      }
243      catch (Exception ex) {
244        closeFormEvent(true, true);
245        this.Close();
246      }
247    }
248
249    /// <summary>
250    /// if one client is clicked, a panel is opened with the details
251    /// </summary>
252    private void ClientClicked() {
253      int i = 0;
254      while (clientInfo.List[i].Name != nameCurrentClient) {
255        i++;
256      }
257      currentClient = clientInfo.List[i];
258      scClientControl.Panel2.Controls.Clear();
259      scClientControl.Panel2.Controls.Add(plClientDetails);
260      pbClientControl.Image = ilClientControl.Images[0];
261      lblClientName.Text = currentClient.Name;
262      lblLogin.Text = currentClient.Login.ToString();
263      lblState.Text = currentClient.State.ToString();
264    }
265
266    /// <summary>
267    /// if one job is clicked, a panel is opened with the details
268    /// </summary>
269    private void JobClicked() {
270      int i = 0;
271      while (jobs.List[i].Id.ToString() != nameCurrentJob) {
272        i++;
273      }
274      lvSnapshots.Enabled = false;
275      int yPos = 0;
276      currentJob = jobs.List[i];
277      scJobControl.Panel2.Controls.Clear();
278      scJobControl.Panel2.Controls.Add(plJobDetails);
279      pbJobControl.Image = ilJobControl.Images[0];
280      lblJobName.Text = currentJob.Id.ToString();
281      progressJob.Value = (int)(currentJob.Percentage * 100);
282      yPos = progressJob.Location.Y;
283      yPos += 20;
284      lblProgress.Location = new Point(
285        lblProgress.Location.X, yPos);
286      lblProgress.Text = (int)(currentJob.Percentage * 100) + "% calculated";
287      yPos += 20;
288      lblUserCreatedJob.Location = new Point(
289        lblUserCreatedJob.Location.X, yPos);
290      lblUserCreatedJob.Text = /* currentJob.User.Name + */ " created Job";
291      yPos += 20;
292      lblJobCreated.Location = new Point(
293        lblJobCreated.Location.X, yPos);
294      lblJobCreated.Text = "Created at " + currentJob.DateCreated;
295      if (currentJob.ParentJob != null) {
296        yPos += 20;
297        lblParentJob.Location = new Point(
298          lblParentJob.Location.X, yPos);
299        lblParentJob.Text = currentJob.ParentJob.Id + " is parent job";
300      }
301      yPos += 20;
302      lblPriorityJob.Location = new Point(
303        lblPriorityJob.Location.X, yPos);
304      lblPriorityJob.Text = "Priority of job is " + currentJob.Priority;
305      if (currentJob.Client != null) {
306        yPos += 20;
307        lblClientCalculating.Location = new Point(
308          lblClientCalculating.Location.X, yPos);
309        lblClientCalculating.Text = currentJob.Client.Name + " calculated Job";
310        yPos += 20;
311        lblJobCalculationBegin.Location = new Point(
312          lblJobCalculationBegin.Location.X, yPos);
313        lblJobCalculationBegin.Text = "Startet calculation at " + currentJob.DateCalculated ;
314       
315        if (currentJob.State == State.finished) {
316          yPos += 20;
317          lblJobCalculationEnd.Location = new Point(
318            lblJobCalculationEnd.Location.X, yPos);
319
320          IJobManager jobManager =
321            ServiceLocator.GetJobManager();
322
323          ResponseObject<JobResult> jobRes = jobManager.GetLastJobResultOf(currentJob.Id);
324
325         
326          lblJobCalculationEnd.Text = "Calculation ended at " + jobRes.Obj.DateFinished;
327        }
328      }                       
329      if (currentJob.State != State.offline) {
330        yPos += 20;
331        lvSnapshots.Location = new Point(
332          lvSnapshots.Location.X, yPos);
333        lvSnapshots.Size = new Size(lvSnapshots.Size.Width,
334          plJobDetails.Size.Height - 10 - yPos);
335        lvSnapshots.Enabled = true;
336      }
337    }
338
339    /// <summary>
340    /// if one user is clicked, a panel is opened with the details
341    /// </summary>
342    private void UserClicked() {
343      int i = 0;
344      while (usersList.List[i].Name != nameCurrentUser) {
345        i++;
346      }
347      currentUser = usersList.List[i];
348      scUserControl.Panel2.Controls.Clear();
349      scUserControl.Panel2.Controls.Add(plUserDetails);
350      pbUserControl.Image = ilUserControl.Images[0];
351      lblUserName.Text = currentUser.Id.ToString();
352    }
353
354    #region Eventhandlers
355    /// <summary>
356    /// Send event to Login-GUI when closing
357    /// </summary>
358    /// <param name="sender"></param>
359    /// <param name="e"></param>
360    private void Close_Click(object sender, EventArgs e) {
361      if (closeFormEvent != null) {
362        closeFormEvent(true, false);
363      }
364      this.Close();
365    }
366
367    /// <summary>
368    /// Send evnt to Login-GUI when closing
369    /// </summary>
370    /// <param name="sender"></param>
371    /// <param name="e"></param>
372    private void HiveServerConsoleInformation_FormClosing(object sender, FormClosingEventArgs e) {
373      if (closeFormEvent != null) {
374        closeFormEvent(true, false);
375      }
376    }
377
378    private void AddJob_Click(object sender, EventArgs e) {
379      AddJobForm newForm = new AddJobForm();
380      newForm.Show();
381      //newForm.addJobEvent += new addDelegate(updaterWoker.RunWorkerAsync);
382    }
383
384    private void Refresh() {
385      AddClients();
386      AddJobs();
387      AddUsers();
388    }
389
390    private void AddUser_Click(object sender, EventArgs e) {
391      AddUserForm newForm = new AddUserForm("User", false);
392      newForm.Show();
393      newForm.addUserEvent += new addDelegate(Refresh);
394    }
395
396    private void AddUserGroup_Click(object sender, EventArgs e) {
397      AddUserForm newForm = new AddUserForm("User", true);
398      newForm.Show();
399      newForm.addUserEvent += new addDelegate(Refresh);                                             
400    }
401
402    private void OnLVClientClicked(object sender, EventArgs e) {
403      nameCurrentClient = lvClientControl.SelectedItems[0].Text;
404      flagClient = true;
405      ClientClicked();
406    }
407
408    private void OnTVClientClicked(object sender, TreeViewEventArgs e) {
409      bool clientgroup = false;
410      foreach (ClientGroup cg in clients.List) {
411        if (tvClientControl.SelectedNode.Text == cg.Name) {
412          clientgroup = true;
413        }
414      }
415      if (clientgroup == false) {
416        nameCurrentClient = tvClientControl.SelectedNode.Text;
417        flagClient = true;
418        ClientClicked();
419      }
420
421    }
422
423    private void OnLVJobControlClicked(object sender, EventArgs e) {
424      nameCurrentJob = lvJobControl.SelectedItems[0].Text;
425      flagJob = true;
426      JobClicked();
427    }
428
429    private void OnTVJobControlClicked(object sender, TreeViewEventArgs e) {
430      try {
431        nameCurrentJob = Convert.ToInt32(tvJobControl.SelectedNode.Text).ToString();
432        flagJob = true;
433        JobClicked();
434      }
435      catch (Exception ex) { }
436
437    }
438
439    private void OnLVUserControlClicked(object sender, EventArgs e) {
440      nameCurrentUser = lvUserControl.SelectedItems[0].Text;
441      flagUser = true;
442      UserClicked();
443    }
444
445    private void OnTVUserControlClicked(object sender, TreeViewEventArgs e) {
446      bool usergroup = false;
447      foreach (UserGroup ug in userGroups.List) {
448        if (tvUserControl.SelectedNode.Text == ug.Name) {
449          usergroup = true;
450        }
451      }
452      if (usergroup == false) {
453        nameCurrentUser = tvUserControl.SelectedNode.Text;
454        flagUser = true;
455        UserClicked();
456      }
457
458    }
459
460
461    private void btnClientClose_Click(object sender, EventArgs e) {
462      scClientControl.Panel2.Controls.Clear();
463      scClientControl.Panel2.Controls.Add(lvClientControl);
464      flagClient = false;
465    }
466 
467    private void btnJobDetailClose_Click(object sender, EventArgs e) {
468      scJobControl.Panel2.Controls.Clear();
469      scJobControl.Panel2.Controls.Add(lvJobControl);
470      flagJob = false;
471    }
472
473    private void btnUserControlClose_Click(object sender, EventArgs e) {
474      scUserControl.Panel2.Controls.Clear();
475      scUserControl.Panel2.Controls.Add(lvUserControl);
476      flagUser = false;
477    }
478
479    private void lvJobControl_MouseMove(object sender, MouseEventArgs e) {
480      if ((lvJobControl.GetItemAt(e.X, e.Y) != null) &&
481        (lvJobControl.GetItemAt(e.X, e.Y).ToolTipText != null)) {
482        tt.SetToolTip(lvJobControl, lvJobControl.GetItemAt(e.X, e.Y).ToolTipText);
483      }
484    }
485
486    private void updaterWoker_DoWork(object sender, DoWorkEventArgs e) {
487
488      IClientManager clientManager =
489          ServiceLocator.GetClientManager();
490     
491      #region ClientInfo
492      ResponseList<ClientInfo> clientInfoOld = clientInfo;
493      clientInfo = clientManager.GetAllClients();
494
495      ResponseList<ClientInfo> clientInfoOldHelp;
496
497      CloneList(clientInfoOld, out clientInfoOldHelp);
498
499      GetDelta(clientInfoOld.List, clientInfoOldHelp.List);
500      #endregion
501
502      #region Clients
503      ResponseList<ClientGroup> clientsOld = clients;
504     
505      clients = clientManager.GetAllClientGroups();
506
507      ResponseList<ClientGroup> clientsOldHelp;
508
509      CloneList(clientsOld, out clientsOldHelp);
510
511      GetDelta(clientsOld.List, clientsOldHelp.List);
512      #endregion
513
514      #region Job
515      ResponseList<Job> jobsOld = jobs;
516      IJobManager jobManager =
517          ServiceLocator.GetJobManager();
518
519      jobs = jobManager.GetAllJobs();
520
521      ResponseList<Job> jobsOldHelp = new ResponseList<Job>();
522      CloneList(jobsOld, out jobsOldHelp);
523     
524      //System.Diagnostics.Debug.WriteLine(jobsOldHelp.List[0].Id.ToString());
525
526      GetDelta(jobsOld.List, jobsOldHelp.List);
527
528      #endregion
529
530    }
531    #endregion
532
533    #region Helper methods
534
535    private void CloneList(ResponseList<Job> oldList, out ResponseList<Job> newList) {
536      newList = new ResponseList<Job>();
537      newList.List = new List<Job>();
538      foreach (Job item in oldList.List) {
539        newList.List.Add(item);
540      }
541    }
542
543    private void CloneList(ResponseList<ClientInfo> oldList, out ResponseList<ClientInfo> newList) {
544      newList = new ResponseList<ClientInfo>();
545      newList.List = new List<ClientInfo>();
546      foreach (ClientInfo item in oldList.List) {
547        newList.List.Add(item);
548      }
549    }
550
551    private void CloneList(ResponseList<ClientGroup> oldList, out ResponseList<ClientGroup> newList) {
552      newList = new ResponseList<ClientGroup>();
553      newList.List = new List<ClientGroup>();
554      foreach (ClientGroup item in oldList.List) {
555        newList.List.Add(item);
556      }
557    }
558
559    private bool IsEqual(ClientInfo ci1, ClientInfo ci2) {
560      if (ci1.ClientId.Equals(ci2.ClientId)) {
561        return true;
562      } else return false;
563    }
564
565    private void GetDelta(IList<ClientInfo> oldClient, IList<ClientInfo> helpClients) {
566      bool found = false;
567
568      foreach (ClientInfo ci in clientInfo.List) {
569        for (int i = 0; i < oldClient.Count; i++) {
570          ClientInfo cio = oldClient[i];
571          if (ci.Id.Equals(cio.Id)) {
572            found = true;
573            if (ci.State != cio.State) {
574              changes.Add(new Changes { Types = Type.Client, ID = ci.Id, ChangeType = Change.Update });
575            }
576            for (int j = 0; j < helpClients.Count; j++) {
577              if (cio.Id.Equals(helpClients[j])) {
578                helpClients.RemoveAt(j);
579                break;
580              }
581            }
582            break;
583          }
584        }
585        if (found == false) {
586          changes.Add(new Changes { Types = Type.Client, ID = ci.Id, ChangeType = Change.Create });
587        }
588        found = false;
589      }
590      foreach (ClientInfo ci in helpClients) {
591        changes.Add(new Changes { Types = Type.Client, ID = ci.Id, ChangeType = Change.Delete });
592      }
593
594    }
595
596    private void GetDelta(IList<ClientGroup> oldClient, IList<ClientGroup> helpClients) {
597
598      bool found = false;
599      foreach (ClientGroup cg in clients.List) {
600        for (int i = 0; i < oldClient.Count; i++) {
601          ClientGroup cgo = oldClient[i];
602          if (cg.Id.Equals(cgo.Id)) {
603            found = true;
604            foreach (Resource resource in cg.Resources) {
605              foreach (Resource resourceold in cgo.Resources) {
606                if (resource.Id.Equals(resourceold.Id)) {
607                  if (resourceold.Name != resource.Name) {
608                    changes.Add(new Changes { Types = Type.Client, ID = cg.Id, ChangeType = Change.Update });
609                  }
610                }
611              }
612            }
613            for (int j = 0; j < helpClients.Count; j++) {
614              if (cgo.Id.Equals(helpClients[j])) {
615                helpClients.RemoveAt(j);
616                break;
617              }
618            }
619            break;
620          }
621        }
622        if (found == false) {
623          changes.Add(new Changes { Types = Type.ClientGroup, ID = cg.Id, ChangeType = Change.Create });
624        }
625        found = false;
626      }
627      foreach (ClientGroup cg in helpClients) {
628        changes.Add(new Changes { Types = Type.ClientGroup, ID = cg.Id, ChangeType = Change.Delete });
629      }
630    }
631     
632    private void GetDelta(IList<Job> oldJobs, IList<Job> helpJobs) {
633      bool found = false;
634      foreach (Job job in jobs.List) {
635       
636        for (int i = 0; i < oldJobs.Count; i++) {
637         
638          Job jobold = oldJobs[i];
639
640          if (job.Id.Equals(jobold.Id)) {
641
642            found = true;
643            if (IsEqual(job.Client, jobold.Client)) {
644              changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Update });
645            } else if (job.DateCalculated != jobold.DateCalculated) {
646              changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Update });
647            }
648
649            for (int j = 0; j < helpJobs.Count; j++) {
650              if (job.Id.Equals(helpJobs[j].Id)) {
651                helpJobs.RemoveAt(j);
652                break;
653              }
654            }
655            break;
656          }
657
658        }
659        if (found == false) {
660          changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Create });
661          System.Diagnostics.Debug.WriteLine("new Job: " + job.Id);
662        }
663        found = false;
664      }
665      foreach (Job job in helpJobs) {
666        changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Delete });
667        System.Diagnostics.Debug.WriteLine("delete Job: " + job.Id);
668      }
669    }
670
671
672    #endregion
673
674
675  }
676}
Note: See TracBrowser for help on using the repository browser.