How to pass multiple requests at a time in WCF/client - c#

With the below code I'm able to process the requests one by one. This is an asynchronous process so I don't need to get a response. I am only passing the requests.
class Program
{
static void Main(string[] args)
{
ProfileRequestData();
}
private static void ProfileRequestData()
{
ProfileRequest.Request[] req = new ProfileRequest.Request[4];
//req.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
req[0] = new ProfileRequest.Request();
req[1] = new ProfileRequest.Request();
req[2] = new ProfileRequest.Request();
req[3] = new ProfileRequest.Request();
req[0].Record = new ProfileRequest.RequestRecord();
req[1].Record = new ProfileRequest.RequestRecord();
req[2].Record = new ProfileRequest.RequestRecord();
req[3].Record = new ProfileRequest.RequestRecord();
req[0].Record.Id = "asdasd123";
req[1].Record.Id = "asdasd456";
req[2].Record.Id = "asdasd789";
req[3].Record.Id = "addjlk123";
ProfileRequest.ProfileRequestClient serviceClient = new ProfileRequest.ProfileRequestClient();
serviceClient.ClientCredentials.UserName.UserName = #"Liberty\nzy0105";
serviceClient.ClientCredentials.UserName.Password = "abcddf";
serviceClient.ProfileRequest(req[0]);
serviceClient.ProfileRequest(req[1]);
serviceClient.ProfileRequest(req[2]);
serviceClient.ProfileRequest(req[3]);
}
}
What I want to do is to process all the requests at a time not one by one.
Can anyone, please, provide the code for the requirement???

For simultaneous jobs like this you should use a threading mechanism. Here you can use backgroundworkers.
var asyncServiceRequester = new BackgroundWorker();
asyncServiceRequester.DoWork += asyncServiceRequester_DoWork;
foreach(var request in req)
{
asyncServiceRequester.RunWorkerAsync(req);
}
this is the code snippet that you should use instead of:
serviceClient.ProfileRequest(req[0]);
serviceClient.ProfileRequest(req[1]);
serviceClient.ProfileRequest(req[2]);
serviceClient.ProfileRequest(req[3]);
and here is the DoWork method of the backgroundworker:
static void asyncServiceRequester_DoWork(object sender, DoWorkEventArgs e)
{
var request = e.Argument as ProfileRequest;//whatever your request type is
serviceClient.ProfileRequest(request);
}
UPDATE:
I am assuming that your user inputs are in a list for dynamic purposes, since you didn't gave any specific information about it. In this case you'll traverse through the list of inputs, and extract the values into your object array. Here is how you would first fill the list of inputs, then how you'll assign those values to your object array.
List<TextBox> inputs = new List<TextBox>();
inputs.Add(input1);
inputs.Add(input2);
...
inputs.Add(inputN);
If your inputs are static than this is how you do it, else;
List<TextBox> inputs = new List<TextBox>();
for(int i = 0; i < someNumber; i++)
{
inputs.Add(new TextBox(){
Text = "some text",
Location = new Point(10, i * 75),
Height = 60,
Width = 150,
Font = new Font(ActiveControl.Font.FontFamily, 10, FontStyle.Regular)
});
}
Rest is pretty straightforward;
var index = 0;
foreach(var tb in inputs)
{
var newReq = new ProfileRequest.Request(){
Record = new ProfileRequest.RequestRecord(){
Id = tb.Text
}
}
req[index++] = req;
// I would suggest you to use generic lists here too since they are simpler and more flexible.
// req.Add(newReq);
}
Gathering the input from a text file or xml should be the topic of another question, but you can do them in the same manner. Just read the file, or xml then extract the values in dynamic manner.

You can create threads to process requests in parallel -
for (int i = 0; i < req.Length; i++)
{
new System.Threading.Thread(() => serviceClient.ProfileRequest(req[i])).Start();
}

Related

Multiple choice application

private void Form1_Load(object sender, EventArgs e)
{
string filePath =
#"C:\Users\User\Documents\flower.txt";
List<string> lines =
File.ReadAllLines(filePath).ToList();
int count = lines.Count();
Random rnd = new Random();
//label1.Text = rnd.Next().ToString();
QuestionsWithAnswer qtn = new.
QuestionsWithAnswer();
string[] line = lines[count - 1].Split(',');
lblQuestion.Text = qtn.question1 = line[0];
radOpt1.Text = qtn.opt1 = line[1];
radOpt2.Text = qtn.opt2 = line[2];
radOpt3.Text = qtn.opt3 = line[3];
radOpt4.Text = qtn.opt4 = line[4];
radOpt5.Text = qtn.opt5 = line[5];
radOpt4.Checked = true;
label1.Text = rnd.Next(count).ToString();
}
I am developing a multiple choice application. This app reads from a text file for its question and options. I want the questions to be generated randomly. The code is working but it's bring same question whenever I load the app the first time even with my random class.
Probably you meant ordering the questions randomly. An easy way would be:
List<string> lines = File
.ReadAllLines(filePath)
.OrderBy(x => Guid.NewGuid()).ToList();
Note: Why wouldn't you use a database instead of a text file.

c# lucene 4.8 slow search: 400ms -> to 30ms?

i try to speed up my lucene-search in my wpf-application.
i hoped that my search would be in the range of about 30ms.
87 search items where found in the index. So that is not very much.
But Stopwatch timer says, it takes around 400ms, way to much for me.
So can u check my code, how i can improve code ?
I also still measured time from the beginning of the try block to the foreach, so there is no big waste of time through init; but it is not (0 ms).
List<CardView> aAll_CardView = new List<CardView>();
try
{
SortField field = new SortField(LUCENT_STATE_MAIN, SortFieldType.STRING);
Sort sort = new Sort(field);
searchManager.MaybeRefreshBlocking(); // execute with fresh index searcher
var searcher = searchManager.Acquire();
var topDocs = searcher.Search(aBooleanQuery, 100, sort);
var _totalHits = topDocs.TotalHits;
CardView aCardView = null;
// measured time: take ~400-500ms grr !!!!
foreach ( var result in topDocs.ScoreDocs)
{
#region iterate through findings and put lucene data into CardView list
var aDoc = searcher.Doc(result.Doc);
aAll_CardView.Add(new CardView
{
// all fields are defined as TextField()...
// must be first, because used in e.g. Nr_Main
RelatedItemCount = aDoc.Get(LUCENT_RELATED_ITEMS),
Nr_Main = aDoc.Get(LUCENT_NR_MAIN),
Nr_Parent = aDoc.Get(LUCENT_NR_PARENT),
Antwort = aDoc.Get(LUCENT_ANTWORT),
Beschreibung = aDoc.Get(LUCENT_BESCHREIBUNG),
Note = aDoc.Get(LUCENT_NOTES),
Question_Main = aDoc.Get(LUCENT_TITLE_MAIN),
Question_Parent = aDoc.Get(LUCENT_TITLE_PARENT),
Book = aDoc.Get(LUCENT_BOOK),
Date_Create = aDoc.Get(LUCENT_DATE_CREATED),
Date_LastEdit = aDoc.Get(LUCENT_DATE_LASTEDIT),
Bibelstelle = aDoc.Get(LUCENT_BIBELSTELLE),
// ParseCore just uses TryParse to get enum for state
Status_Main = ParseCore(aDoc.Get(LUCENT_STATE_MAIN)),
Status_Parent = ParseCore(aDoc.Get(LUCENT_STATE_PARENT))
});
#endregion
}
}
catch(Exception e)
{
string exp = e.ToString();
new JMsg(exp).ShowDialog();
}
finally
{
}

Passing multiple line items with GP webservice

Below is the code I'm working with to pass multiple line items to create sales order through GP Web service. I can pass single Line Item without any problem , but when I pass multiple Items it is only taking the last one. The array has around 5 Item ID and I'm passing fixed Quantity as 15, Need to make both dynamic. But for the testing purpose I'm trying like this. I know the problem with the creation/initialization of some web service objects. As novice to the entire set of things I couldn't find the exact problem.
C# Code
CompanyKey companyKey;
Context context;
SalesOrder salesOrder;
SalesDocumentTypeKey salesOrderType;
CustomerKey customerKey;
BatchKey batchKey;
// SalesOrderLine salesOrderLine;
ItemKey orderedItem;
Quantity orderedAmount;
Policy salesOrderCreatePolicy;
DynamicsGPClient wsDynamicsGP = new DynamicsGPClient();
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.UserName = "Admin";
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.Password = "pass";
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.Domain = "Gp";
System.ServiceModel.WSHttpBinding binding;
binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);
context = new Context();
companyKey = new CompanyKey();
companyKey.Id = (1);
context.OrganizationKey = (OrganizationKey)companyKey;
salesOrder = new SalesOrder();
salesOrderType = new SalesDocumentTypeKey();
salesOrderType.Type = SalesDocumentType.Order;
salesOrder.DocumentTypeKey = salesOrderType;
customerKey = new CustomerKey();
customerKey.Id = "121001";
salesOrder.CustomerKey = customerKey;
batchKey = new BatchKey();
batchKey.Id = "RMS";
salesOrder.BatchKey = batchKey;
// SalesOrderLine[] orders = new SalesOrderLine[6];
SalesOrderLine[] lines = { };
for (int i = 1; i < 5; i++)
{
SalesOrderLine salesOrderLine = new SalesOrderLine();
orderedItem = new ItemKey();
orderedItem.Id = Arr[i].ToString();
salesOrderLine.ItemKey = orderedItem;
orderedAmount = new Quantity();
orderedAmount.Value = 15;
salesOrderLine.Quantity = orderedAmount;
lines = new SalesOrderLine[] { salesOrderLine };
MessageBox.Show(lines.Count().ToString());
}
salesOrder.Lines = lines;
//salesOrder.Lines = orders;
salesOrderCreatePolicy = wsDynamicsGP.GetPolicyByOperation("CreateSalesOrder", context);
wsDynamicsGP.CreateSalesOrder(salesOrder, context, salesOrderCreatePolicy);
if (wsDynamicsGP.State != CommunicationState.Faulted)
{
wsDynamicsGP.Close();
}
MessageBox.Show("Success");
lines = new SalesOrderLine[] { salesOrderLine }; will recreate the lines array object each time meaning you loose any previously added objects. Effectively only the final object in the loop is actually added.
Try using a List<T> like so:
SalesOrderLine[] lines = { }; Becomes List<SalesOrderLine> lines = new List<SalesOrderLine>();
lines = new SalesOrderLine[] { salesOrderLine }; Becomes: lines.Add(salesOrderLine);
If its important you end up with an array as the input:
salesOrder.Lines = lines; Becomes: salesOrder.Lines = lines.ToArray();

Apply any kind of Updates on database immedieately C#

I have this program where I want to create a button base from Products on my database(ProductTbl). I found a way to do that
Here's the code:
public void DynamicButton() //Function for retrieving record and creating a button for each product
{
string select = "select ProductID,ProductDesc,ProductPrice,ProductPic from ProductTbl" ;
sda = new SqlDataAdapter(select,sqlConn);
sda.Fill(dataTable);
for (int i = 0; i < dataTable.Rows.Count; i++)
{
ExtendedButton prodBtn = new ExtendedButton(); //with ExtendedButton this time
prodBtn._itemName = dataTable.Rows[i][1].ToString();//this asigns the product name to the extended button
prodBtn._itemID = Convert.ToInt32(dataTable.Rows[i][0]);
prodBtn._myPrice = Convert.ToDecimal(dataTable.Rows[i][2]);
prodBtn.BackgroundImageLayout = ImageLayout.Stretch;
prodBtn.Click += new EventHandler(OnButtonClick);
prodBtn.Height = 100;
prodBtn.Width = 100;
System.Drawing.Font f1 = SystemFonts.DefaultFont;
prodBtn.Font = new System.Drawing.Font(f1.FontFamily,f1.Size,FontStyle.Bold);
prodBtn.Text = dataTable.Rows[i][1].ToString();
prodBtn.TextAlign = ContentAlignment.BottomCenter;
prodBtn.ForeColor = Color.White;
prodBtn.BackgroundImageLayout = ImageLayout.Zoom;
toolTip1.Show(prodBtn.Text, prodBtn);
byte[] image = (byte[])dataTable.Rows[i][3];
prodBtn.BackgroundImage = imgConverter.byteArrayToImage(image);
prodBtn.TextAlign = ContentAlignment.MiddleCenter;
flowPanel.Controls.Add(prodBtn);
}
}
//You can see this at codeproject
Now the problem is that whenever i add a product on that table using Stored procedure. I don't know how i can sync updates to the datatable that I use with this one. Any ideas and suggestion will be highly appreciated. Thanks sorry for the long post
You can use ASP.Net Caching with SqlCacheDependency.
See this page for details:
https://msdn.microsoft.com/en-us/library/ms178604.aspx

Parallel task on tree structure not complete

Very new to .NET task parallelism. The objective is walking through a tree structure, where each branch is composed of one parent node, one child node and one operation node(like a weight). And for each node, create an extension object and save it to db. I followed a possible duplicate conversation. But the observation is that the tree is not walked through completely. The process would exit early unexpectedly. Following is my code:
public void InitializeScheduleVariables_Parallel(IResource ANode, double aNumRequired, double aBatchRequired, double aAcceptProbability, AppContext aAppContext, bool ARecursively = true)
{
var LTasks = new List<Task>();
var LUser = aAppContext.LocalContext.User;
LTasks.Add(Task.Factory.StartNew(() =>
{
var LNewContext = new AppContext(new DbContext(new Context(LUser)));
var LNewRep = new ResourceRepository(LNewContext);
ANode = LNewRep.Get(ANode.Id);
ANode.ResourceInstance_Create(); // Create the ResourceInstance on the Resourse if it not already exists.
ANode.ResourceInstance.Required = aNumRequired;
ANode.ResourceInstance.ScheduleSource = ResourceInstance.ScheduleSourceEnum.Undefined;
ANode.ResourceInstance.ScheduleState = ResourceInstance.ScheduleStateEnum.Unscheduled;
ANode.ResourceInstance.ScheduleMode = ResourceInstance.ScheduleModeEnum.Undefined;
ANode.ResourceInstance.BatchRequired = aBatchRequired;
ANode.ResourceInstance.ProbabilityOfCompletion = aAcceptProbability;
ANode.ResourceInstance.Save();
}));
if (ARecursively)
{
foreach (AssemblyLink LAssembly in ANode.GetOutEdges())
{
LTasks.Add(Task.Factory.StartNew(() =>
{
// SET The Variables for the Production Operations AS WELL
IOperationResource LOperation = LAssembly.Operation;
if (LOperation != null)
{
var LNewContext = new AppContext(new DbContext(new Context(LUser)));
var LNewRep = new OperationResourceRepository(LNewContext);
LOperation = LNewRep.Get(LOperation.Id);
LOperation.ResourceInstance_Create(); // Create the ResourceInstance on the Resourse if it not already exists.
LOperation.ResourceInstance.Required = aNumRequired / LAssembly.OutputQuantity;
LOperation.ResourceInstance.BatchRequired = aBatchRequired / LAssembly.OutputQuantity;
LOperation.ResourceInstance.ScheduleSource = ResourceInstance.ScheduleSourceEnum.Undefined;
LOperation.ResourceInstance.ScheduleState = ResourceInstance.ScheduleStateEnum.Unscheduled;
LOperation.ResourceInstance.ScheduleMode = ResourceInstance.ScheduleModeEnum.Undefined;
LOperation.ResourceInstance.ProbabilityOfCompletion = aAcceptProbability;
LOperation.ResourceInstance.Save();
}
}));
LTasks.Add(Task.Factory.StartNew(() =>
{
// Recursively SET Child NODES
IResource LChildNode = LAssembly.Child;
double LNumRequired_Child = aNumRequired * LAssembly.InputQuantity / LAssembly.OutputQuantity;
double LNumBatchRequired_Child = LChildNode.Quantity * LAssembly.InputQuantity / LAssembly.OutputQuantity;
InitializeScheduleVariables_Parallel(LChildNode, LNumRequired_Child, LNumBatchRequired_Child, aAcceptProbability, aAppContext, ARecursively);
}));
}
}
Task.WaitAll(LTasks.ToArray());
}
Could anyone share some thought? Thank you.

Categories

Resources