There is such a code, how can it be simplified?
I have a problem with canceling task in c#, task[0] does not stop executing. Here is the code.
cts1 = new CancellationTokenSource();
cts2 = new CancellationTokenSource();
cts3 = new CancellationTokenSource();
cts4 = new CancellationTokenSource();
cts5 = new CancellationTokenSource();
cts6 = new CancellationTokenSource();
cts7 = new CancellationTokenSource();
cts8 = new CancellationTokenSource();
Task _cockroach1 = SetSpeed(cockroach1, 1);
Task _cockroach2 = SetSpeed(cockroach2, 2);
Task _cockroach3 = SetSpeed(cockroach3, 3);
Task _cockroach4 = SetSpeed(cockroach4, 4);
Task _cockroach5 = SetSpeed(cockroach5, 5);
Task _cockroach6 = SetSpeed(cockroach6, 6);
Task _cockroach7 = SetSpeed(cockroach7, 7);
Task _cockroach8 = SetSpeed(cockroach8, 8);
private async Task SetSpeed(Image _cockroach, int _number)
{
while (_x <= 830)
{
if (_number == 1 && cts1.Token.IsCancellationRequested) return; //остановка таска
if (_number == 2 && cts2.Token.IsCancellationRequested) return;
if (_number == 3 && cts3.Token.IsCancellationRequested) return;
if (_number == 4 && cts4.Token.IsCancellationRequested) return;
if (_number == 5 && cts5.Token.IsCancellationRequested) return;
if (_number == 6 && cts6.Token.IsCancellationRequested) return;
if (_number == 7 && cts7.Token.IsCancellationRequested) return;
if (_number == 8 && cts8.Token.IsCancellationRequested) return;
It's not very clear how to stop tasks.
Instead of having 9 variables, why not just store all the elements into an array or a list?
var cts = Enumerable.Range(0, 9).Select(x => new CancellationTokenSource()).ToArray();
var cockroach = Enumerable.Range(0, 9).Select(x => new CockRoach(...)).ToArray();
var _cockroaches = cts.Select((x, i) => SetSpeed(cockroach[i], i);
private async Task SetSpeed(Image _cockroach, int _number)
{
while (_x <= 830)
{
if (cts[number].Token.IsCancellationRequested) return;
}
// ...
}
When you don't like LINQ-syntax, you can also use good old-styled loops:
var cts = new CancellationTokenSource[9];
var cockroaches = new Image[9];
var _cockroaches = new Task[9];
for(int i = 0; i < 9; i++)
{
cts[i] = new CancellationTokenSource();
cockroaches[i] = new Image(...);
_cockroaches [i] = SetSpeed(cockroaches[i], i);
}
Related
Same question was asked for python here: Selenium - wait until element is present, visible and interactable. However the answers are not covering all the scenarios.
My implementation fails from time to time, when I am not in debug mode.
I consider that waiting for an ID is such a trivial task that should have a straight forward KISS implementation and should never fail.
public IWebElement WaitForId(string inputId, bool waitToInteract = false, int index = 0)
{
IWebElement uiElement = null;
while (uiElement == null)
{
var items = WebDriver.FindElements(By.Id(inputId));
var iteration = 0;
while (items == null || items.Count < (index + 1) ||
(waitToInteract && (!items[index].Enabled || !items[index].Displayed)))
{
Thread.Sleep(500);
items = WebDriver.FindElements(By.Id(inputId));
if (items.Count == 0 && iteration == 10)
{
// "still waiting...: " + inputId
}
if (iteration == 50)
{
// "WaitForId not found: " + inputId
Debugger.Break(); // if tried too many times, maybe you want to investigate way
}
iteration++;
}
uiElement = WebDriver.FindElement(By.Id(inputId));
}
return uiElement;
}
public IWebElement GetActiveElement(string id, int allowedTimeout = 20, int retryInterval = 250)
{
var wait = new DefaultWait<IWebDriver>(_driver)
{
Timeout = TimeSpan.FromSeconds(allowedTimeout),
PollingInterval = TimeSpan.FromMilliseconds(retryInterval)
};
return wait.Until(d =>
{
var element = d.FindElement(By.Id(id));
return element.Displayed || element.Enabled ? element : throw new NoSuchElementException();
});
// Usage would be something like this
GetActiveElement("foo").SendKeys("Bar");
You should be able to create extension method and call the extension instead
public static class WebDriverExtension
{
public static IWebElement GetActiveElement(this IWebDriver driver, string id, int allowedTimeout = 20, int retryInterval = 250)
{
var wait = new DefaultWait<IWebDriver>(driver)
{
Timeout = TimeSpan.FromSeconds(allowedTimeout),
PollingInterval = TimeSpan.FromMilliseconds(retryInterval)
};
return wait.Until(d =>
{
var element = d.FindElement(By.Id(id));
return element.Displayed || element.Enabled ? element : throw new NoSuchElementException();
});
}
}
// usage
_driver.GetActiveElement("foo").SendKeys("bar");
I have a search query which search for all jobs in the database and than displays them in accordance to the most recent ones filtering the data by date as follows:
result = db.AllJobModel.Where(a => a.JobTitle.Contains(searchTitle) && a.locationName.Contains(searchLocation)).ToList());
result = (from app in result orderby DateTime.ParseExact(app.PostedDate, "dd/MM/yyyy", null) descending select app).ToList();
result = GetAllJobModelsOrder(result);
after that I have a method GetAllJobModelsOrder which displays jobs in order which seems to be work fine but in my case its not ordering jobs so I need to understand where I am wrong:
private List<AllJobModel> GetAllJobModelsOrder(List<AllJobModel> result)
{
var list = result.OrderBy(m => m.JobImage.Contains("job1") ? 1 :
m.JobImage.Contains("job2") ? 2 :
m.JobImage.Contains("job3") ? 3 :
m.JobImage.Contains("job4") ? 4 :
m.JobImage.Contains("job5") ? 5 :
6)
.ToList();
return list;
}
The result I get is about 10 jobs from job1 and than followed by other jobs in the same order what I would like to achieve is to filter the most recent jobs than display one job from each type of a job.
An example of the input would be as follows:
AllJobModel allJobModel = new AllJobModel
{
JobDescription = "Description",
JobImage = "Job1",
JobTitle = "title",
locationName = "UK",
datePosted = "15/06/2020",
}
The output that I get is as follows:
In where result should be mixed from different jobs.
Excepted resulta as follows a specific order of job source--1. TotalJob[0] :: 2. MonsterJob[0] :: 3. Redd[0] :: 4. TotalJob[ 1 ] :: 5. MonsterJob[ 1 ] ::6. Redd[ 1 ]:
I have tried the following solution but list data structure seems to be not stroing data in order:
private List<AllJobModel> GetAllJobModelsOrder(List<AllJobModel> result)
{
string lastItem = "";
List<AllJobModel> list = new List<AllJobModel>();
int pos = -1;
while(result.Count != 0)
{
for(int i = 0; i < result.Count; i++)
{
if(result[i].JobImage.Contains("reed") && (lastItem == "" || lastItem == "total" || lastItem == "monster"))
{
pos++;
list.Insert(pos,result[i]);
lastItem = "reed";
result.Remove(result[i]);
break;
}else if (result[i].JobImage.Contains("total") && (lastItem == "reed" || lastItem == "monster" || lastItem == "" ))
{
pos++;
list.Insert(pos, result[i]);
lastItem = "total";
result.Remove(result[i]);
break;
}else if(result[i].JobImage.Contains("monster.png") && (lastItem =="total" || lastItem == "reed" || lastItem == "" ))
{
pos++;
list.Insert(pos, result[i]);
lastItem = "monster";
result.Remove(result[i]);
break;
}else if(result[i].JobImage.Contains("reed") &&( lastItem == "reed"))
{
if(result.FirstOrDefault(a=>a.JobImage.Contains("total") || a.JobImage.Contains("monster")) != null)
{
lastItem = "total";
break;
}
else
{
pos++;
list.Insert(pos, result[i]);
lastItem = "reed";
result.Remove(result[i]);
break;
}
}
else if (result[i].JobImage.Contains("total") && (lastItem == "total"))
{
if (result.FirstOrDefault(a => a.JobImage.Contains("reed") || a.JobImage.Contains("monster")) != null)
{
lastItem = "monster";
break;
}
else
{
pos++;
list.Insert(pos, result[i]);
lastItem = "total";
result.Remove(result[i]);
break;
}
}
else if (result[i].JobImage.Contains("monster") && (lastItem == "monster"))
{
if (result.FirstOrDefault(a => a.JobImage.Contains("total") || a.JobImage.Contains("reed")) != null)
{
lastItem = "reed";
break;
}
else
{
pos++;
list.Insert(pos, result[i]);
lastItem = "monster";
result.Remove(result[i]);
break;
}
}
}
}
return list;
}
also what I found is that the value of the elements in the list is different from what its actual value. So I am not sure if this is an error with my code or with visual studio:
you can use the below concept here. I am sorting a list based on the numeric value at the end of each string value using Regex.
List<string> ls = new List<string>() { "job2", "job1", "job4", "job3" };
ls = ls.OrderBy(x => Regex.Match(x, #"\d+$").Value).ToList();
Certainly the requirement was not as straight forward as initially thought. Which is why I am offering a second solution.
Having order by and rotate the offering "Firm" in a type of priority list for a set number of times and then just display whatever comes after that requires a custom solution. If the one algorithm you have works and you are happy then great. Otherwise, I have come up with this algorithm.
private static List<AllJobModel> ProcessJobs(List<AllJobModel> l)
{
var noPriorityFirst = 2;
var orderedList = new List<AllJobModel>();
var priorityImage = new string[] { "TotalJob", "MonsterJob", "Redd" };
var gl = l.OrderBy(o => o.datePosted).GroupBy(g => g.datePosted).ToList();
foreach (var g in gl)
{
var key = g.Key;
for (int i = 0; i < noPriorityFirst; i++)
{
foreach (var j in priorityImage)
{
var a = l.Where(w => w.datePosted.Equals(key) && w.JobImage.Equals(j)).FirstOrDefault();
if (a != null)
{
orderedList.Add(a);
var ra = l.Remove(a);
}
}
}
foreach (var j in l.ToList())
{
var a = l.Where(w => w.datePosted.Equals(key)).FirstOrDefault();
if (a != null)
{
orderedList.Add(a);
var ra = l.Remove(a);
}
}
}
return orderedList;
}
To test this process I have created this Console app:
static void Main(string[] args)
{
Console.WriteLine("Start");
var l = CreateTestList();
var lJobs = ProcessJobs(l);
lJobs.ForEach(x => Console.WriteLine($"{x.datePosted} : {x.JobImage}"));
}
private static List<AllJobModel> CreateTestList()
{
var orderedList = new List<AllJobModel>();
var l = new List<AllJobModel>();
var priorityImage = new string[] { "TotalJob", "MonsterJob", "Redd" };
var rand = new Random();
var startTime = DateTime.Now;
for (int i = 0; i < 20; i++)
{
var j = rand.Next(0, priorityImage.Length);
var h = rand.Next(0, 4);
var a = new AllJobModel();
a.JobDescription = "Desc " + i;
a.JobImage = priorityImage[j];
a.JobTitle = "Title" + i;
a.locationName = "UK";
a.datePosted = startTime.AddDays(h);
l.Add(a);
}
for (int i = 0; i < 20; i++)
{
var j = rand.Next(0, priorityImage.Length);
var h = rand.Next(0, 4);
var a = new AllJobModel();
a.JobDescription = "Desc " + i;
a.JobImage = "Job " + i;
a.JobTitle = "Title" + i;
a.locationName = "UK";
a.datePosted = startTime.AddDays(h);
l.Add(a);
}
return l;
}
I got a problem related with the TaskCompletionSource object and the Dismiss function of an alert. This problem does not appear within the IOS version of the application
When the application sends an notification, two alerts with working functionality will show up when the user activates the application:
Authentication
Filling in a value.
However, when I enter the application I only get to see the authentication(because this alert is called first within the app) and the second alert never shows up. I already tried to override the Dismiss function and set the TaskCompletionSource object result to null, but this causes the same alert to appear an X times before the application crashes. Is there a way to repeat the TaskCompletionSource object so that I can see all the alerts? Or what kind of modifications do I need to make on the Dismiss function so that the TaskCompletionSource is completed once all the alerts are shown?
Android Fragment Example code:
public static readonly int AlertWidth = Device.Idiom == TargetIdiom.Phone ? 270 : 320;
class AlertDialogFragment : DialogFragment
{
public string Title;
public string Body;
public View Content;
public List<AlertButton> Buttons;
public TaskCompletionSource<object> tsc;
public Dialog AndroidCustomAlert(Activity activ)
{
Android.Views.LayoutInflater inflater = Android.Views.LayoutInflater.From(activ);
Android.Views.View view = inflater.Inflate(Resource.Layout.AlertDialogLayout, null);
AlertDialog.Builder builder = new AlertDialog.Builder(activ);
builder.SetView(view);
Android.Widget.TextView title = view.FindViewById<Android.Widget.TextView>(Resource.Id.Login);
title.Text = Title;
Android.Widget.TextView body = view.FindViewById<Android.Widget.TextView>(Resource.Id.pincodeText);
body.Text = Body;
body.MovementMethod = new Android.Text.Method.ScrollingMovementMethod();
Android.Widget.EditText pincode = view.FindViewById<Android.Widget.EditText>(Resource.Id.pincodeEditText);
Android.Widget.Button btnPositive = view.FindViewById<Android.Widget.Button>(Resource.Id.btnLoginLL);
Android.Widget.Button btnNegative = view.FindViewById<Android.Widget.Button>(Resource.Id.btnClearLL);
Android.Widget.Button btnNeutral = view.FindViewById<Android.Widget.Button>(Resource.Id.btnNeutral);
if (Title.Contains("Time"))
{
Android.Views.View secondView = inflater.Inflate(Resource.Layout.TimePickerLayout, null);
builder.SetView(secondView);
btnPositive = secondView.FindViewById<Android.Widget.Button>(Resource.Id.btnLoginLL);
btnNegative = secondView.FindViewById<Android.Widget.Button>(Resource.Id.btnClearLL);
var tp = secondView.FindViewById<Android.Widget.TimePicker>(Resource.Id.timePicker1);
tp.SetIs24HourView((Java.Lang.Boolean)true);
//Positive button feedback
btnPositive.Text = Buttons.Last().Text;
btnPositive.Click += delegate
{
var car = (Xamarin.Forms.TimePicker)Content;
var ts = new TimeSpan(tp.Hour, tp.Minute, 0);
car.Time = ts;
CommandsForButtons(Buttons.Last());
};
//Negative button feedback
btnNegative.Text = Buttons.First().Text;
btnNegative.Click += delegate
{
CommandsForButtons(Buttons.First());
};
}
else if (Title.Contains("How are you"))
{
btnPositive.Visibility = Android.Views.ViewStates.Gone;
btnNegative.Visibility = Android.Views.ViewStates.Gone;
btnNeutral.Visibility = Android.Views.ViewStates.Visible;
pincode.Visibility = Android.Views.ViewStates.Gone;
var happySlider = view.FindViewById<Android.Widget.SeekBar>(Resource.Id.happinessSlider);
happySlider.SetProgress(5, false);
happySlider.Visibility = Android.Views.ViewStates.Visible;
btnNeutral.Text = Buttons.First().Text;
btnNeutral.Click += delegate
{
var car = (StackLayout)Content;
var layoutView = (Xamarin.Forms.AbsoluteLayout)car.Children[1];
var slider = (Slider)layoutView.Children[1];
var totalHappyValue = happySlider.Progress / 10;
slider.Value = totalHappyValue;
CommandsForButtons(Buttons.First());
};
}
else
{
//Checks if there are no buttons, and if there aren't any, creates a neutral one
if (Buttons == null || Buttons.Count == 0)
{
btnPositive.Visibility = Android.Views.ViewStates.Gone;
btnNegative.Visibility = Android.Views.ViewStates.Gone;
btnNeutral.Visibility = Android.Views.ViewStates.Visible;
pincode.Visibility = Android.Views.ViewStates.Gone;
Buttons = new List<AlertButton> {
new AlertButton {
Text = "Oké",
IsPreferred = true,
Action = () => false
}
};
btnNeutral.Text = Buttons.First().Text;
btnNeutral.Click += delegate
{
CommandsForButtons(Buttons.First());
};
}
if (Content == null)
{
pincode.Visibility = Android.Views.ViewStates.Gone;
}
//Positive button feedback
btnPositive.Text = Buttons.Last().Text;
btnPositive.Click += delegate
{
var test = (StackLayout)Content;
if (test != null)
{
var car = (Entry)test.Children[0];
car.Text = pincode.Text;
}
CommandsForButtons(Buttons.Last());
};
//Negative button feedback
btnNegative.Text = Buttons.First().Text;
btnNegative.Click += delegate
{
CommandsForButtons(Buttons.First());
};
}
return builder.Create();
}
public void CommandsForButtons(AlertButton button)
{
Func<Task> dismiss = null;
var command = new Command(async () =>
{
var ab = button;
var cont = true;
if (ab.Action != null)
cont = ab.Action();
if (ab.ActionAsync != null)
{
cont = cont && await ab.ActionAsync();
}
if (!cont)
{
await dismiss();
}
});
dismiss = async () =>
{
dismiss = async () => { };
await Task.Run(() =>
{
Dismiss();
tsc.SetResult(null);
});
Log.Debug("TSC", tsc.Task.Status.ToString());
};
command.Execute(this);
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
var test = AndroidCustomAlert(Activity);
test.SetCanceledOnTouchOutside(false);
return test;
}
public override void Dismiss()
{
base.Dismiss();
}
}
public async Task Show(string title, string body, View content, List<AlertButton> buttons)
{
var tcs = new TaskCompletionSource<object>();
var adf = new AlertDialogFragment
{
Title = title,
Body = body,
Content = content,
Buttons = buttons,
tsc = tcs
};
var FragmentManager = ((Activity)Forms.Context).FragmentManager;
FragmentTransaction ft = FragmentManager.BeginTransaction();
//Remove fragment else it will crash as it is already added to backstack
Fragment prev = FragmentManager.FindFragmentByTag("alert");
if (prev != null)
{
ft.Remove(prev);
}
ft.AddToBackStack(null);
adf.Show(ft, "alert");
await tcs.Task;
}
The methods:
await Authentication();
await UserCheck();
And the IOS code:
public static readonly int AlertWidth = Device.Idiom == TargetIdiom.Phone ? 270 : 320;
public async Task Show(string title, string body, View content, List<AlertButton> buttons)
{
if (buttons == null || buttons.Count == 0)
{
buttons = new List<AlertButton> {
new AlertButton {
Text = "Oké",
IsPreferred = true,
Action = () => false
}
};
}
Func<Task> dismiss = null;
var captionSize = (double)StyleKit.PhoneDarkLabelStyles.Caption.Setters.First(s => s.Property == Label.FontSizeProperty).Value;
var titleSize = (double)StyleKit.PhoneDarkLabelStyles.Title.Setters.First(s => s.Property == Label.FontSizeProperty).Value;
var top = new StackLayout {
Padding = new Thickness(15, 20, 15, 20),
Spacing = 3,
Children = {
new Label {
Text = title,
Style = StyleKit.PhoneDarkLabelStyles.Title,
FontSize = Math.Max(16, titleSize),
HorizontalTextAlignment = TextAlignment.Center
},
new Label {
Text = body,
Style = StyleKit.PhoneDarkLabelStyles.Body,
//FontSize = ,
FontSize = Math.Max(14, captionSize),
HorizontalTextAlignment = TextAlignment.Center
} ,
new ContentView {
Padding = new Thickness(0,5,0,-10),
VerticalOptions = LayoutOptions.EndAndExpand,
Content = content
}
}
};
var buttonViews = buttons.Select(ab => new Button {
FontSize = Math.Max(16, titleSize),
Text = ab.Text,
FontAttributes = ab.IsPreferred ? FontAttributes.Bold : FontAttributes.None,
TextColor = ab.IsDestructive ? Color.Red : Color.Default,
Command = new Command(async () => {
var cont = true;
if (ab.Action != null)
cont = ab.Action();
if (ab.ActionAsync != null)
cont = cont && await ab.ActionAsync();
if (!cont)
await dismiss();
})
}).ToList();
var grid = new Grid {
RowDefinitions = {
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto }
},
ColumnSpacing = 0,
RowSpacing = 0
};
buttons.ForEach(button => {
grid.ColumnDefinitions.Add(
new ColumnDefinition {
Width = AlertWidth / buttonViews.Count
}
);
});
for (int i = 0; i < buttonViews.Count; i++)
{
grid.Children.Add(new BorderView {
BorderColor = Color.FromRgba(0,0,0,0.2),
Thickness = new Thickness(0, 1, (i + 1 < buttonViews.Count) ? 1 : 0, 0)
}, i, 1);
grid.Children.Add(buttonViews[i], i, 1);
}
grid.Children.Add(top, 0, buttons.Count, 0, 1);
var box = new Frame {
WidthRequest = AlertWidth,
BackgroundColor = Color.FromRgba(1,1,1,0.96),
Padding = 0,
Content = grid
};
var outer = new AbsoluteLayout {
BackgroundColor = Color.FromRgba(0,0,0,0.65),
Opacity = 0,
Children = { box }
};
AbsoluteLayout.SetLayoutFlags(box, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(box,
new Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
var page = new ContentPage {
Content = /* new ScrollView { Content = */ outer // }
};
var tcs = new TaskCompletionSource<object>();
var topVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (topVC.PresentedViewController != null) {
topVC = topVC.PresentedViewController;
}
var vc = page.CreateViewController();
topVC.Add(vc.View);
var innerView = vc.View.Subviews[0].Subviews[0];
vc.View.RemoveFromSuperview();
dismiss = async () => {
dismiss = async () => {};
await outer.FadeTo(0, 50);
innerView.RemoveFromSuperview();
tcs.SetResult(null);
};
topVC.Add(innerView);
var kbh = new KeyboardHelper();
kbh.KeyboardChanged += async (sender, e) => {
await box.TranslateTo(0, e.Visible ? (-e.Height / 2f) : 0, 100, Easing.CubicInOut);
};
await outer.FadeTo(1, 100);
await tcs.Task;
}
This looks like an and/or problem between threading or simply not setting the task completion.
In the IOS version you have
dismiss = async () => {
dismiss = async () => {};
await outer.FadeTo(0, 50);
innerView.RemoveFromSuperview();
tcs.SetResult(null);
};
There is no matching tcs.SetResult(null); statement in the android version.
Also of note is the async invocation, as waiting to call SetResult will block the main thread without it.
It takes lot of time to execute these loops due to for loop implementation
How can I replace it to be more fast, the under laying table do not have much records too, plus I have made the primary keys too , but still the for loops are slow
public List<BusinessLayer.Transactions.CDANumberTracking> GetPOUnusedCDANumberTrackingItems(string code)
{
List<BusinessLayer.Transactions.CDANumberTracking> results = new List<BusinessLayer.Transactions.CDANumberTracking>();
List<Entity.Transactions.CDANumberTracking> SoUsedBagList = new List<Entity.Transactions.CDANumberTracking>();
List<Entity.Transactions.POCDANumberTracking> rejects = new List<SalesOrderModule.Entity.Transactions.POCDANumberTracking>();
List<Entity.Transactions.POCDANumberTracking> returns = new List<SalesOrderModule.Entity.Transactions.POCDANumberTracking>();
List<Entity.Transactions.POCDANumberTracking> rejectList = new List<SalesOrderModule.Entity.Transactions.POCDANumberTracking>();
List<Entity.Transactions.POCDANumberTracking> returnRejectList = new List<SalesOrderModule.Entity.Transactions.POCDANumberTracking>();
List<Entity.Transactions.POCDANumberTracking> SearchList = new List<SalesOrderModule.Entity.Transactions.POCDANumberTracking>();
try
{
if (!InOpenLookup)
(Connection as SQL).BeginTransaction();
DataLayer.Tables.PLSPOCDANumberTrackingDNew sampleTable = new SalesOrderModule.DataLayer.Tables.PLSPOCDANumberTrackingDNew(this.Connection);
sampleTable.SearchCriteria[0].Value = code.Trim();
sampleTable.SearchCriteria[1].Value = (int)0;
List<Entity.Transactions.POCDANumberTracking> results1 = sampleTable.Reads(false);
if (results1.Count > 0)
{
rejectList.AddRange(results1);
}
DataLayer.Tables.PLSPOCDANumberTrackingReturnD sampleTable2 = new SalesOrderModule.DataLayer.Tables.PLSPOCDANumberTrackingReturnD(this.Connection);
sampleTable2.SearchCriteria[0].Value = code.Trim();
List<Entity.Transactions.POCDANumberTracking> results2 = sampleTable2.Reads(false);
if (results2.Count > 0)
{
returnRejectList.AddRange(results2);
}
DataLayer.Tables.PLSPOCDANumberTrackingD sampleTable3 = new SalesOrderModule.DataLayer.Tables.PLSPOCDANumberTrackingD(this.Connection);
sampleTable3.SearchCriteria[0].Value = code.Trim();
SearchList = sampleTable3.Reads(false);
DataLayer.Tables.PSOMCDANumberTrackingD sampleTable4 = new SalesOrderModule.DataLayer.Tables.PSOMCDANumberTrackingD(this.Connection, null);
sampleTable4.SearchCriteria[3].Value = code.Trim();
sampleTable4.SearchCriteria[6].Value = false;
SoUsedBagList = sampleTable4.Read(false);
//process data...
Entity.Transactions.POCDANumberTracking temp;
foreach (Entity.Transactions.POCDANumberTracking rejectItem in rejectList)
{
for (int i = rejectItem.From; i <= rejectItem.To; i++)
{
temp = new SalesOrderModule.Entity.Transactions.POCDANumberTracking();
temp.From = i;
temp.To = i;
temp.Code = rejectItem.Code.Trim();
temp.GrnNo = rejectItem.GrnNo.Trim();
temp.WbcNo = rejectItem.WbcNo.Trim();
rejects.Add(temp);
}
}
//returns
foreach (Entity.Transactions.POCDANumberTracking returnItem in returnRejectList)
{
for (int i = returnItem.From; i <= returnItem.To; i++)
{
temp = new SalesOrderModule.Entity.Transactions.POCDANumberTracking();
temp.From = i;
temp.To = i;
temp.Code = returnItem.Code.Trim();
temp.GrnNo = returnItem.GrnNo.Trim();
temp.WbcNo = returnItem.WbcNo.Trim();
returns.Add(temp);
}
}
Entity.Transactions.CDANumberTracking temp2;
Entity.Transactions.CDANumberTracking temp3;
Entity.Transactions.POCDANumberTracking temp4;
foreach (Entity.Transactions.POCDANumberTracking searchItem in SearchList)
{
for (int i = searchItem.From; i <= searchItem.To; i++)
{
temp = null;
temp3 = null;
temp4 = null;
//check if the bag is on reject list
temp = rejects.Find(delegate(Entity.Transactions.POCDANumberTracking tc) { return (tc.From == i && tc.WbcNo.Trim().ToUpper() == searchItem.WbcNo.Trim().ToUpper() && tc.GrnNo.Trim().ToUpper() == searchItem.GrnNo.Trim().ToUpper()); });
if (temp != null)
continue;
//check if the bag is on return list
temp4 = returns.Find(delegate(Entity.Transactions.POCDANumberTracking tcc) { return (tcc.From == i && tcc.GrnNo.Trim().ToUpper() == searchItem.GrnNo.Trim().ToUpper()); });
if (temp4 != null)
continue;
//check if the bag is alredy used in So module...
temp3 = SoUsedBagList.Find(delegate(Entity.Transactions.CDANumberTracking cda) { return (cda.Code.Trim().ToUpper() == searchItem.Code.Trim().ToUpper() && cda.BagNo == searchItem.From); });
if (temp3 != null)
continue;
temp2 = new SalesOrderModule.Entity.Transactions.CDANumberTracking();
temp2.BagNo = i;
temp2.Code = searchItem.Code.Trim();
temp2.LineNo = 0;
temp2.Location = string.Empty;
temp2.WbcNo = string.Empty;
temp2.ID = null;
temp2.IsReturned = false;
temp2.IsSelected = false;
temp2.ItemNo = string.Empty;
temp2.Status = SalesOrderModule.Entity.ModifyStatus.New;
results.Add(BusinessLayer.Transactions.CDANumberTracking.GetCDANumberTracking(this, temp2, null));
}
}
if (!InOpenLookup)
(Connection as SQL).EndTransaction();
}
catch (Exception er)
{
if (!InOpenLookup)
(Connection as SQL).Rollback();
throw er;
}
return results;
}
the for loop under second for each need to placed ... need some help
You should factor out of the inner loop everything you can. As the code stands right now, you are unecessarily repeating the following operations:
returnItem.Code.Trim();
returnItem.GrnNo.Trim();
returnItem.WbcNo.Trim();
I have nowhere near enough information to judge if this will have any performance impact.
Other suspects are new SalesOrderModule.Entity.Transactions.POCDANumberTracking() and returns.Add(temp). If returns is somekind of ordered list, then this could have a considerable performance hit. If its a simple List then it shouldn't and there isn't much you could do to improve it anyways.
Concerning the constructor, only you know how expensive it is but there is not much you can do to avoid it either.
All that said, your code would look something like this:
Entity.Transactions.POCDANumberTracking temp;
foreach (Entity.Transactions.POCDANumberTracking returnItem in returnRejectList)
{
var code = returnItem.Code.Trim();
var grnNo = returnItem.GrnNo.Trim();
var wbcNo = returnItem.WbcNo.Trim();
for (int i = returnItem.From; i <= returnItem.To; i++)
{
temp = new SalesOrderModule.Entity.Transactions.POCDANumberTracking();
temp.From = i;
temp.To = i;
temp.Code = code;
temp.GrnNo = grnNo;
temp.WbcNo = wbcNo;
returns.Add(temp);
}
}
I have to limit the entries coming under the foreach loops, that is best way by debugging the code
so the data layer codes referring in the
sampleTable.Reads(false);
sampleTable2.Reads(false);
sampleTable3.Reads(false);
sampleTable4.Reads(false);
need to modified by including the Item for search (I mean the SQL STATEMENTS)
I'm trying to optimize a heavy process with some tasks, but it seems that after the first iteration it skips the ProcessQueue method run.
private void ImportSheet(Excel.Worksheet Data)
{
this._ImportedSlurry = new ConcurrentQueue<AnalizedDataDTO>();
this._LastRowReached = false;
this._CurrentRow = this._FirstRow;
while(!this._LastRowReached)
{
AnalizedDataDTO ImportedRow = this.ValidateRow(Data, _CurrentRow);
Task task1 = Task.Run(() => ProcessQueue(Enumerable.Range(this._CurrentRow, 50).ToArray(),Data));
Task task2 = Task.Run(() => ProcessQueue(Enumerable.Range(this._CurrentRow+50, 50).ToArray(),Data));
Task.WaitAll(task1, task2);
this._CurrentRow += 100;
}
}
private void ProcessQueue(int[] range, Excel.Worksheet Data)
{
for (int i = range.First(); i < range.Length; i++)
{
AnalizedDataDTO ImportedRow = this.ValidateRow(Data, i);
if (ImportedRow == null)
{
this._LastRowReached = true;
break;
}
else
{
this._ImportedSlurry.Enqueue(ImportedRow);
}
}
}
The problem is your for-loop, to be specific its if-condition.
You should either iterate over range, i.e.
foreach (var i in range)
or iterate over an index, i.e.
foreach (var idx = 0; idx < range.Length; idx++)
{
var i = range[idx];
For example assume that this._CurrentRow == 100, then your version of the for loop would look like:
for (int i = 100 /* range.First() */; i < 50 /* range.Length */; i++)