C#, Counting iterations for a complaint process - c#

i have to create a programme that will handle complaints i have to track how many times i complete the process, this means i will need a count that increases when i return to the first form in the process however the number always resets when the first form is opened
runNum is set to a public int this is the code i have for entering data ito the form automatically then increaseing the runmber before opening the next form so far:
private void autoFill()
{
TitlePage titlepage = new TitlePage();
if (titlepage.getRun() == true)
{
int priority = runNum % 4;
if (priority == 0)
priority = 2;
txtDate.Text = DateTime.Today.ToString("dd/MM/yyyy");
txtRef.Text = (100 + runNum).ToString();
txtPriority.Text = priority.ToString();
txtCustName.Text = firstNames[runNum] + " " + secondNames[runNum];
txtCustAddress.Text = (runNum + 5).ToString() + " " + Address1[runNum] + " " + Address2[(runNum % 7)];
txtCustEmail.Text = firstNames[runNum] + secondNames[runNum] + "#" + ISP[(runNum % 10)] + "." + Suff[(runNum % 10)];
txtCustTel.Text = TelNo[runNum];
//TBD- fill this in with actual data
rtbComplaint.Text = "Complaint type, Sevarity, soultion exsiting, employee who dealt with complaint, Date";
rtbComplaint.Enabled = false;
txtPriority.Enabled = false;
txtDate.Enabled = false;
txtRef.Enabled = false;
txtCustName.Enabled = false;
txtCustName.Enabled = false;
txtCustEmail.Enabled = false;
txtCustAddress.Enabled = false;
txtCustTel.Enabled = false;
if (runNum % 2 == 0)
{
rdoNo.Checked = true;
enter code here }
else
{
rdoYes.Checked = true;
}
getTimer();
runNum++;
}
}

A public int will always be reset in this case. You should declare a static int on your parent page if you want global access to the variable. But global variables are to be avoided. Rather try to save your iterations in a central point such as a database or file which you can retrieve the value from or even use a server cached object which you can update and get the value from again.

i would go with a static variable but be aware that even static variables can be reset if the appdomain is restarted or the webpage class gets recompiled.
see
Lifetime of ASP.NET Static Variable
edited: sorry i assumed this question was a for an asp.net application. is this not the case?
if its a normal windows form then you will need to store it in some server side, whether DB, shared file on a server or something similar

Related

The instance of entity type +cannot be tracked because another instance with the same key value

I have the following code
double csave = (double)FindAcc(memid).MovAmt;
double psave = (double)FindAcc(memid).VolSafe;
double psaveamt = (double)FindAcc(memid).PriSave;
Single compAmt = 0;
ToxAccInfo ta = new ToxAccInfo();
ta.MemId = (int?)memid;
ta.AccId = (long)FindAcc(memid).AccId;
The ta.AccID is the primary key for the table ToxAccInfo.
Issue is when I attempt to save changes without the ta.AccId = (long)Find(memid).Accid, it creates another line instead of updating the original. But, when I now add the line, it fails with the error The instance of entity type...cannot be tracked because another instance with the same key value.
I have spent the past 3 days trying to find a work around but still can't get it to work.
Thank you.
I am adding the whole procedure to create what is to be saved (ta) and the saving subroutine
public IEnumerable<ToxAccInfo> UpdateBoth(DateTime stdate, DateTime spdate, long memid, bool chkcomp, bool chkvol)
{
double csave = (double)FindAcc(memid).MovAmt;
double psave = (double)FindAcc(memid).VolSafe;
double psaveamt = (double)FindAcc(memid).PriSave;
Single compAmt = 0;
var ta = new ToxAccInfo();
ta.MemId = (int?)memid;
//ta.AccId = (long)FindAcc(memid).AccId;
for (DateTime curdate = stdate; curdate <= spdate; curdate = curdate.AddMonths(1))
{
if (GoAhead(memid, curdate))
{
ta.MovAmt = csave;
ta.VolSafe = psave;
if (chkvol == true)
{
ta.VolSafe = psave + psaveamt;
//ta.VolSafe += psaveamt;
}
if (curdate.Month > 1 && curdate.Year >= 2011)
{
compAmt = 1000;
}
else
{
compAmt = 200;
}
if (chkcomp == true)
{
ta.MovAmt = csave + compAmt; //do the check for year it changed to 1000
}
ta.Done = curdate;
ta.Udate = curdate;
ta.Amt = compAmt + psaveamt;
//check for interest for month 12 and year greater than 2007.
if (curdate.Month == 12 && curdate.Year >= 2017)
{
ta.VolSafe = doInterest((decimal)ta.VolSafe);
ta.MovAmt = doInterest((decimal)ta.MovAmt);
psave = (double)ta.VolSafe;
csave = (double)ta.MovAmt;
goto jumper;
}
//psave += psaveamt;
//csave += compAmt;
psave = (double)ta.VolSafe;
csave = (double)ta.MovAmt;
jumper:;
}
}
yield return UpdateMemAccount(ta);
}
private ToxAccInfo UpdateMemAccount(ToxAccInfo UpAm)
{
_db.ToxAccInfos.Update(UpAm);
_db.SaveChanges();
return null;
}
The error occurs after the yield calls private ToxAccInfo UpdateMemAccount(ToxAccInfo UpAm), at _db.ToxAccinfos.Update(UpAm);, I have tried using add instead of Update still the same issue.
I call Updateboth from the controller with the following code, the two methods are in an interface. The code below calls the interface.
case "Commit Update":
ViewData["taa"] = _ar.UpdateBoth(stdate, eddate, (int)_ar.FindAcc(long.Parse(HttpContext.Session.GetString("memberid"))).MemId, chkcomp, chkvol).ToList();
ViewBag.isSet = false;
break;
Here is what i assuming your code doing:
FindAcc(memid) will use the DbContext to select the entity base on the memid (this is your unique value), then extract the value out of it.
After that, you create another instance and assign the same key to that along with the modified values you want.
But unfortunately, the AccId is your PK, and ta.AccId = (long)Find(memid).Accid make it another new instance with the same Id that got tracked by the EF Core itself while it select the entity back by the FindAcc(memid).
What you might want to do:
If you want to update that entity:
var entityFromDb = FindAcc(memid);
entityFromDb.volSafe = SomeNewValueHere;
YourDbContext.SaveChange();
If you want to add another entity:
var entityFromDb = FindAcc(memid);
var ta = new ToxAccInfo();
ta.volSafe = SomeNewValueHere;
YourDbContext.YourToxAccInfoSet.Add(ta);
YourDbContext.SaveChange();
Furthur information can be found here

Change multiple, similarly named variable values at the same time

First time on stackOverflow, so this might be a really nooby question, but i was wondering if i could change multiple variable values at the same time without having to write out every single one.
Here is my code at the moment:
public string Label1Text()
{
int index;
for (index = 0; index < 32; index++)
{
if (seatChosen[index])
{
_bookedSeats += "A" + (index + 1) + " ";
Properties.Settings.Default.A1 = true;
}
}
string text = _bookedSeats + ".";
//debug
label1.Text = text;
return text;
}
The line
Properties.Settings.Default.A1 = true;
is what i want to change to something like this (theoretical code)
Properties.Settings.Default.A[index] = true;
or
Properties.Settings.Default.A + index = true;
I hope you can understand what I'm trying to accomplish.
Using reflection: (I'm assuming Properties.Settings.Default is a static class, and A1, A2, etc. are public static properties.)
Type type = typeof(Properties.Settings.Default);
var prop = type.GetProperty(index.ToString("\\A0"));
if (prop != null)
prop.SetValue(null, true);
If Default is an instance, you would need to pass it to SetValue instead of null. Also, C# v6 allows a more concise syntax.
Type type = Properties.Settings.Default.GetType();
type.GetProperty($"A{index}")?.SetValue(Properties.Settings.Default, true);

What is wrong with the if else if else statement in this C# script?

I am having trouble with a C# script that uses the Sony Vegas Pro scripting API to generate an edit list of video clips for trimming in ffmpeg. The full script and details of the purpose can be found at http://www.sonycreativesoftware.com/forums/showmessage.asp?forumid=21&messageid=932542.
Part of my script is shown below. When I run the script I get the error "The name 'OffsetAdjusterFrames' does not exist in the current context", relating to the line Timecode OffsetAdjuster = Timecode.FromFrames(OffsetAdjusterFrames); , and "The name 'DurationAdjusterFrames' does not exist in the current context" relating to the next line.
The problem seems to be with the line if (clipOffsetOriginalFrames == 0) or with something else in that if else if else statement. If I bypass the whole of that if else if else statement by commenting it out and explicitly declaring OffsetAdjusterFrames and DurationAdjusterFrames then the rest of the script works.
Any help would be appreciated as I have run out of things to try. Thanks.
Edit: This is different to enter link description here because this is C# and that is Java, so it's not really a duplicate, but the general solution is the same.
...
Timecode clipOffsetOriginal = videoEvent.ActiveTake.Offset;
// clipOffsetOriginal as a number of frames
Int64 clipOffsetOriginalFrames = videoEvent.ActiveTake.Offset.FrameCount;
Timecode clipOffset = clipOffsetOriginal - startAdd;
Timecode clipDuration = videoEvent.Length + startAdd + endAdd;
// Reset start to zero if start was not trimmed at all, and compensate length
if (clipOffsetOriginalFrames == 0)
{
int OffsetAdjusterFrames = 2;
int DurationAdjusterFrames = -2;
}
// Reset start to zero if start had been trimmed by just 1 frame, and compensate length
else if (clipOffsetOriginalFrames == 1)
{
int OffsetAdjusterFrames = 1;
int DurationAdjusterFrames = -1;
}
else
{
int OffsetAdjusterFrames = 0;
int DurationAdjusterFrames = 0;
}
Timecode OffsetAdjuster = Timecode.FromFrames(OffsetAdjusterFrames);
Timecode DurationAdjuster = Timecode.FromFrames(DurationAdjusterFrames);
Timecode clipOffsetAdjusted = clipOffset + OffsetAdjuster;
Timecode clipDurationAdjusted = clipDuration + DurationAdjuster;
// Convert start and duration from timecode to seconds
double start = clipOffsetAdjusted.ToMilliseconds() / 1000;
double duration = clipDurationAdjusted.ToMilliseconds() / 1000;
string triminfo = String.Format(basename + ".mp4 " + start + " " + duration);
...
The variables OffsetAdjusterFrames and DurationAdjusterFrames are declared inside the if statement, so they are local variables and can't be called from outside your if statements.
When you move the declaration outside of the if statement, say into the method, it works because the scope of the variable is in the method, so can be called outside of the if statement as long as it's within the method.
So basically just declare the variables at the start of the method, like this:
int OffsetAdjusterFrames;
int DurationAdjusterFrames;
and then assign the values in your if statements like this:
// Reset start to zero if start was not trimmed at all, and compensate length
if (clipOffsetOriginalFrames == 0)
{
OffsetAdjusterFrames = 2;
DurationAdjusterFrames = -2;
}
// Reset start to zero if start had been trimmed by just 1 frame, and compensate length
else if (clipOffsetOriginalFrames == 1)
{
OffsetAdjusterFrames = 1;
DurationAdjusterFrames = -1;
}
else
{
OffsetAdjusterFrames = 0;
DurationAdjusterFrames = 0;
}

Objects Passed to ParameterizedThreadStart being overwritten?

Background:
I'm working on a small app that will read Events from an Eventlog remotely via WMI. Basically I'm searching for when a workstation locks and unlocks.
Problem:
I create an array of threads. I loop through my dataset (computernames) and fire off multiple
ParameterizedThreadStart objects with a custom object (LockHunterArgs). The problem is that I know my dataset doesn't have duplicates in it. I added a console.writeline to the end of the thread function and it displays duplicates.
Also, before I tried using threads. If I ran the code synchronously it functioned fine. It just took a long time. So that's why I'm trying to introduce multithreading.
Example Output:
//...Snipped some unique lines above
Computer: COMP Time: 3/29/2012 8:05:11 AM Session: 3935dd76-6a10-41a9-bd96-86143c66482d
Computer: COMP Time: 3/29/2012 8:05:11 AM Session: 3935dd76-6a10-41a9-bd96-86143c66482d
//...Snipped some unique and duplicated lines below
My Hypothesis:
If I place a breakpoint in the first few lines of the get_lock_data function where it is casting and step to the next line. It is random. It will step forward once then hit the same line twice. I have even seen it go two lines down then go backwards. I assume that this is because I'm firing off threads and it is hitting the points at different times giving the illusion that it is going backwards. But it is almost like the object that is being passed in is being overwritten by later threads.
I tried creating another array of LockHunterArgs and creating and assigning them during the thread firing process but that also didn't work.
It is probably something dumb. Thanks in advance.
// lance
Code:
public class LockHunterArgs
{
public LockHunterArgs(string comp, DateTime limit, Guid session)
{
Computer = comp;
LimitTime = limit;
sessionID = session;
}
public string Computer;
public DateTime LimitTime;
public Guid sessionID;
}
public class LockHunter
{
private void get_lock_data(object args)
{
string computer = ((LockHunterArgs)args).Computer;
DateTime limitTime = ((LockHunterArgs)args).LimitTime;
Guid sessionID = ((LockHunterArgs)args).sessionID;
//....SNippet ... code connects to the box and pulls data...
Console.WriteLine("Computer: " + computer + " Time: " + limitTime.ToString() + " Session: " + sessionID.ToString());
}
public void HuntLocks()
{
//....Snippet... code connects to database and gets a list of objects (currentSessions)
Thread[] threadArray = new Thread[currentSessions.Count];
int cnt = 0;
foreach (LINQ.session sesson in currentSessions)
{
DateTime mostRecentTimestamp = (from q in db.actions
where q.session_id == sesson.uid
orderby q.timestamp descending
select q.timestamp).FirstOrDefault();
ParameterizedThreadStart start = new ParameterizedThreadStart(get_lock_data);
threadArray[cnt] = new Thread(start);
threadArray[cnt].Start(new LockHunterArgs(sesson.computername , mostRecentTimestamp, sesson.uid));
cnt++;
}
for (int i = 0; i < threadArray.Length; i++)
{
threadArray[i].Join();
}
Console.WriteLine(DateTime.Now.ToString() + " Threads have joined");
//....Snippet of saving the gathered data from the threads to the database
}
}
Solution:
I added a new class. Then looped through my LINQ-to-SQL results to create a list of that new class. Then I base my thread firing from that list instead of the LINQ-to-SQL generated one. All is well. Can anyone explain this?
public class TempSession
{
public TempSession(LINQ.session sess)
{
this.computername = sess.computername;
this.timestamp = sess.start_time;
this.uid = sess.uid;
}
public string computername;
public DateTime timestamp;
public Guid uid;
}
public void HuntLocks()
{
//select EventCode,TimeGenerated,Message from Win32_NTLogEvent WHERE logfile='Security' and (EventCode='4800' or EventCode='4801') and TimeGenerated > '20120327 08:08:08'
// 4800 = locked
// 4801 = unlocked
LINQ.Login_ActionsDataContext db = new LINQ.Login_ActionsDataContext();
List<LINQ.session> currentSessions = (from q in db.sessions
where q.end_time == null
orderby q.computername ascending
select q).ToList();
// START Solution Changes
List<TempSession> newCurrentSessions = new List<TempSession>();
foreach (LINQ.session session in currentSessions)
{
newCurrentSessions.Add(new TempSession(session));
}
Thread[] threadArray = new Thread[newCurrentSessions.Count];
// END solution changes
for (int i = 0; i < newCurrentSessions.Count; i++)
{
DateTime mostRecentTimestamp = (from q in db.actions
where q.session_id == newCurrentSessions[i].uid
orderby q.timestamp descending
select q.timestamp).FirstOrDefault();
ParameterizedThreadStart start = new ParameterizedThreadStart(get_lock_data);
threadArray[i] = new Thread(start);
threadArray[i].Start(new LockHunterArgs(newCurrentSessions[i].computername, mostRecentTimestamp, newCurrentSessions[i].uid));
}
for (int i = 0; i < threadArray.Length; i++)
{
threadArray[i].Join();
}
Console.WriteLine(DateTime.Now.ToString() + " Threads have joined");
db.actions.InsertAllOnSubmit(newActions);
Console.WriteLine(DateTime.Now.ToString() + " Found " + newActions.Count.ToString() + " locks");
db.SubmitChanges();
newActions = new List<LINQ.action>();
}
Use a temp variable to store the iterated value:
foreach (LINQ.session sesson in currentSessions)
{
var tempSession = session; // now use tempSession
....
This is a known side effect of closure of the iterated value.
I would say the problem is most likely in what you snipped out. I was unable to reproduce your issue with this faked data:
var guids = Enumerable.Range(1, 10)
.Select(i => Guid.NewGuid())
.ToArray();
var currentSessions = Enumerable.Range(1, 10)
.Select(i => new {computername = "pc" + i})
.Zip(guids,(a,g) => new {a.computername, uid = g});
var dbactions = Enumerable.Range(1, 10)
.Select(i => DateTime.Now.AddHours(-1*i))
.Zip(guids, (t,g) => new {session_id = g, timestamp = t});
Given this, can you provide a working example that isn't dependent on any of your local resources?

Facebook c# SDK returning less results than original number

I am getting album photos and there are total of 44 photos in that album but sdk is returning me just 25 results. Is this some limitation or we have to ask for next 25?
My code so far is:
dynamic photos = app.Get(AlbumList[currentAlbumSelectedIndex].Id + "/photos");
int infoCount = 0;
foreach (dynamic albumPhoto in photos.data)
{
Classes.MyPhoto photoData = new Classes.MyPhoto();
photoData.Id = albumPhoto.id;
if (albumPhoto.name != null && albumPhoto.name.ToString().Length >100)
photoData.MyPhotoName = albumPhoto.name.ToString().Substring(0, 90) + "...";
else
photoData.MyPhotoName = albumPhoto.name;
byte[] imageBytes = function.GetImageFromUrl(albumPhoto.source);
Statuslabel.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
{
if (imageBytes != null)
photoData.MyPhotoPicture = function.GetBitmapImage(imageBytes);
System.Windows.Forms.Application.DoEvents();
Statuslabel.Content = "Getting info of " + infoCount + " / " + photos.data.Count;
AlbumPhotoList.Add(photoData);
if (imageAlbumPhotos.Source == null)
{
imageAlbumPhotos.Source = AlbumPhotoList[0].MyPhotoPicture;
labelAlbumPics.Content = AlbumPhotoList[0].MyPhotoName;
AlbumPictureGetProgress.Visibility = System.Windows.Visibility.Hidden;
}
if (currentAlbumDisplayingPicture < AlbumList.Count - 1)
buttonNextAlbumPic.IsEnabled = true;
}));
infoCount++;
}
in your example you are using the method call
app.Get(AlbumList[currentAlbumSelectedIndex].Id + "/photos");
As far as I know, you should be able to pass an IDictionary<string, object> as second parameter. There you define the "offset" parameter.
I read about the offset parameter in the facebook api reference in section Reading > Paging.
Hope this helps, Martin
Well it is not a problem but it is a limit that in order to keep the working efficent it returns only 25 results by default you can ask for as many results.Giving it Offset and limit Values
not the code becomes like this
dynamic parameters = new ExpandoObject();
parameters.limit = 50;
parameters.offset = 0;
dynamic friends = app.Get("me/photos",parameters);

Categories

Resources