|
I also wanted to ask what are the best frameworks to improve the appearance of buttons. Microsoft has made no effort in this regard. I use DevComponents DotNetBar but it seems that few people use it and wanted to know what you are using.
modified 29-Mar-17 7:19am.
|
|
|
|
|
Regequion wrote: Microsoft has made no effort in this regard. I prefer plain WinForms, because of the effort they have made.
It is a very recognizable button, and it will look like that uniformly across all applications. There is no guessing involved for the user on what the control would do or how to use it.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Have you looked at WPF? With WPF you can do anything you want to any element, so you can create the look and feel you need with very little work.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
This is a bit long but I really need some validation on my project. I would appreciate your thoughts on the overall design and also my questions at the end
Overview
I'm creating an app that will run individual assemblies (called "Services") in a Windows Service. The Windows Service will really just be a host for the service classes that can be run according to a schedule. A "Service" is just an an assembly that implements an interface. Its run duration is determined by a schedule. It can run one time, or repeatedly according to scheduling options.
The Windows Service will be running on remote instruments around the world. The Windows Service will listen to a SignalR service running on our server that will all us to install, start, stop, disable, remove, or change the schedule for any or all of the "Services" on a particular instrument.
An example of a use case is diagnostics. A service will execute every 5 minutes to query a local DB for error records, then report its findings back to our server. The will be other use cases as well.
Details
On startup of the Windows Service the app will load services from a 'manifest'. This file is just a serialized list of services to load and when to run them. If an assembly is not runable (because the schedule says not to run, or it's been disabled), the it's not loaded.
Here's the manifest, not including the scheduling details.
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfService xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Service>
<ServiceName>TestClass1</ServiceName>
<ServiceId>59182d7e-8874-4d40-bdba-44936bcce815</ServiceId>
<AssemblyName>Services.Test.dll</AssemblyName>
<State>Ready</State>
</Service>
</ArrayOfService>
Assemblies that can be run will implement this interface
public interface IService
{
event EventHandler<ServiceMessageModel> StatusChanged;
string ServiceName { get; set; }
Guid ServiceId { get; set; }
ServiceState State { get; set; }
void Start();
void Stop();
}
For each item in the manifest the app will create an instance of each class and store that reference in a list:
private void LoadServices()
{
_services = new List<IService>();
string[] files = Directory.GetFiles(_servicesLocation, "*.dll");
foreach (string file in files)
{
var assemblyExistsInManifest = _manifest.Where(x => file.Contains(x.AssemblyName)).Any();
if (assemblyExistsInManifest)
{
Assembly assembly = Assembly.LoadFrom(file);
var types = assembly.GetTypes();
foreach (Type type in types)
{
var typeExistsInManifest = _manifest.Where(x => type.ToString().Contains(x.ServiceName)).Any();
var implementsInterface = typeof(IService).IsAssignableFrom(type);
if (typeExistsInManifest && implementsInterface)
var serviceClass = Activator.CreateInstance(type) as IService;
serviceClass.StatusChanged += ServiceClass_StatusChanged;
_services.Add(serviceClass);
}
}
}
}
}
Next, the list is iterated and each service in it is started in its own thread
private void StartAllServices()
{
foreach (var service in _services)
{
Task.Factory.StartNew(() =>
{
service.Start();
});
}
}
This is the basic idea and some code that I already have in place.
Questions
1) Cancelling / Pausing. I need to be able to stop a service from further processing. This could mean the service remains loaded but does not continue processing, or it could mean actually cancelling the task the service is running is so it can be unloaded.
This means that I would need to store separate CancellationTokenSource instances for each service as they're loaded in the StartService method above so that I can call Cancel() on a task for a specific service. If I defined the CancellationTokenSource as a property on the IService interface, then the StartServices method could create the CancellationTokenSource and assign it to the service at the time it is started.
This would allow my CancelService method to look like this
private void CancelService(Guid serviceId)
{
var service = _services.FirstOrDefault(x => x.ServiceId == serviceId);
if (service != null)
{
var ct = service.CancellationToken;
ct.Cancel();
}
}
Any thoughts on this?
2) Error Handling. Assuming an exception happens inside a service, this should not "crash" the service but instead set its State to Error and report that to the Host running on our server. The Windows Service portion should catch exceptions thrown by the services and report that back to the server. At no point should an exception cause either the Windows Service or any service to stop running. Any thoughts on this?
Summary
I'm VERY new to TPL and have little to no experience with it, so this design may be totally wrong. If so, please share your thoughts on a more stable approach. I would also appreciate any example code you may have.
Thank you
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 28-Mar-17 14:42pm.
|
|
|
|
|
Starting the services: I'd prefer to have some kind of thread owned by a class implementing IService. In its Start method, that thread is created and started. Use a try...catch inside the loop of the main method (or in the Timer_Elapsed event, if you use a timer). Start/Stop can be controlled with a boolean member variable _keepRunning - just check it in the loop.
Error Handling: Add an "error event" to IService which gets subscribed by the Windows service. Ideally, it contains some information about how corrupted the state of that service is, such that the main service can decide if it's appropriate to unload it and create a new instance.
|
|
|
|
|
If I understand what you're saying.. it would mean creating the thread and error handling INSIDE the service classes, correct?
If so, it puts the responsibility on individual developers to follow the pattern to make it work.
Classes implementing IService only really need to have some basic info (Id, Name) and Start and Stop methods that the Windows Service can call into.
Am I understanding what you're saying here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Can you provide a small example to illustrate what you're saying here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I'm creating a class instance using Activator.CreateInstance
var serviceClass = Activator.CreateInstance(type) as IInstrumentService;
_services.Add(serviceClass);
Then, later, I start each service. I want to catch any exceptions that occur in the service class. I was thinking about something like
private void StartAllServices()
{
foreach (var service in _services)
{
Task.Factory.StartNew(() =>
{
service.Start();
}).ContinueWith(task =>
{
if (task.Exception != null)
{
}
});
}
}
Any reason this would not work? Know of a better way to do this?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Hi Kevin,
So does your service have a Stop() method as well? Normally a start method would be kind of asynchronous in nature, kicking off its own threads, opening network listeners and that sort of thing, so the test you have there looks like it would catch exceptions in just that part.
Or is it that Start() method is more of a Run()? By which I means it runs until completion, possibly days later?
A good catch all would be this (lifted from Visual Studio right in front of me):
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Regards,
Rob Philpott.
|
|
|
|
|
Yes, the services have a Stop method. The services are independent of each other. They can each do entirely different things.
There will be a schedule in place that each services runs under. One may run only once, while another may run regularly at different days & times.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Just a quick note:
Passing a cancellation token to the Task.Factory.StartNew() will give you an external control for your child tasks.
Otherwise I've been playing with the same construct for a component host (except that I hydrate my components via a MEF ImportMany) and it works very well.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
The as operator can return null . If you're not sure whether the type implements the interface, you should check for null before you add the service to the list. If you are sure, or you want an exception if it doesn't, then switch to using a cast instead:
var serviceClass = Activator.CreateInstance(type) as IInstrumentService;
if (serviceClass != null) _services.Add(serviceClass);
var serviceClass = (IInstrumentService)Activator.CreateInstance(type);
_services.Add(serviceClass);
You could pass TaskContinuationOptions.OnlyOnFaulted , which would remove the need to test whether the task has an exception.
.ContinueWith(task =>
{
}, TaskContinuationOptions.OnlyOnFaulted);
Also, Task.Run is generally preferred over Task.Factory.StartNew :
Task.Run vs Task.Factory.StartNew | Parallel Programming with .NET[^]
Task.Run(() => service.Start()).ContinueWith(...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
How to read random line from text file that startswith * and lines below him that are related to him?
I have created to get random line with question using commands below, but after that it doesn't read lines below him that are related to him,instead of that he read lines from beggining!!!
var questions =
File.ReadLines(filePath)
.Where(line => line.StartsWith("*")).ToList();
var rng = new Random();
var myRandomQuestion = questions[rng.Next(questions.Count)].Substring(1);
label1.Text = myRandomQuestion;
My text file has 15000 lines.Lines with * character are questions and lines below them are terms relating to that question.
This is one part of file:
*Planete i njihovi sateliti
Zemlja=Mesec
Mars=Fobos
Jupiter=Io
Saturn=Titan
Uran=Titania
Neptun=Triton
Pluton=Haron
Merkur=Nema satelit
*Čuveni parovi iz umetnosti
Hamlet=Ofelija
Ruslan=Ljudmila
Zevs=Hera
Otelo=Dezdemona
Paris=Helena
Abelard=Eloiza
Paolo=Frančeska
Lanselot=Ginevra
*Latinski pojmovi
Kvalifikacija=Osposobljenost
Karantin=Izolacija
Radijacija=Zračenje
Ratifikacija=Potpisivanje
Racionalan=Razuman
Reakcija=Otpor
Realizacija=Ostvarenje
Rekapitulacija=Ponavljanje
*Poveži aktuelne predsednike sa državama u kojima vladaju.
Trajan Basesku=Rumunija
Karolos Papuljas=Grčka
Đorđo Napolitano=Italija
Tomas Hendrik Ilves=Estonija
Danilo Tirk=Slovenija
Dimitris Hristofias=Kipar
Tarja Halonen=Finska
Meri Mekelis=Irska
*Francuski gradovi
Bordeaux=Bordo
Auxerre=Okser
Toulouse=Tuluz
Nantes=Nant
Marseille=Marselj
Dijon=Dižon
Limoges=Limož
Chateauroux=Šatero
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.IO;
namespace Slagalica
{
public partial class Spojnice : MetroFramework.Forms.MetroForm
{
public Spojnice()
{
InitializeComponent();
}
string igra;
int j = 0;
Button[] button;
private void Spojnice_Load(object sender, EventArgs e)
{
Random r = new Random();
int indeks;
igra = "spojnice";
StreamReader sr = new StreamReader(igra + ".txt");
string[] niz1 = new string[8];
string[] niz2 = new string[8];
var questions = File.ReadLines(igra + ".txt").Where(line => line.StartsWith("*")).ToList();
var myRandomQuestion = questions[r.Next(questions.Count)].Substring(1);
label1.Text = myRandomQuestion;
button = new Button[] { button1, button2, button3, button4, button5, button6, button7, button8
,button9, button10, button11, button12, button13, button14, button15, button16 };
for (int i = 0; i < 8; i++)
{
string s = sr.ReadLine();
niz1[i] = s.Substring(0, s.IndexOf('='));
indeks = r.Next(1, 9);
bool ind = true;
while (ind)
{
ind = false;
switch (indeks)
{
case 1:
if (button9.Text == "")
button9.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 2:
if (button10.Text == "")
button10.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 3:
if (button11.Text == "")
button11.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 4:
if (button12.Text == "")
button12.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 5:
if (button13.Text == "")
button13.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 6:
if (button14.Text == "")
button14.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 7:
if (button15.Text == "")
button15.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
case 8:
if (button16.Text == "")
button16.Text = s.Substring(s.IndexOf('=') + 1);
else
{
indeks = r.Next(1, 9);
ind = true;
}
break;
}
}
}
for (j = 0; j < 8; j++)
button[j].Text = niz1[j];
for (j = 0; j < 16; j++)
button[j].BackColor = Color.DodgerBlue;
label1.BackColor = Color.DodgerBlue;
timer1.Enabled = true;
}
int ukupno = 0, pojam = 0;
private void RacunajZaDugme(Button dugme1, Button dugme2, string igr)
{
string s1 = dugme1.Text + "=" + dugme2.Text;
StreamReader sr = new StreamReader(igr + ".txt");
string s2 = sr.ReadLine();
while (!sr.EndOfStream)
{
s2 = sr.ReadLine();
if (s1 == s2)
{
ukupno += 4;
dugme1.BackColor = Color.Green;
dugme2.BackColor = Color.Green;
break;
}
if (s1 != s2)
{
dugme1.BackColor = Color.Red;
}
}
pojam++;
if (pojam == 8)
{
KrajIgre();
pojam = 0;
ukupno = 0;
}
}
private void KrajIgre()
{
timer1.Enabled = false;
button = new Button[] { button1, button2, button3, button4, button5, button6, button7, button8
,button9, button10, button11, button12, button13, button14, button15, button16 };
for (j = 0; j < 16; j++)
button[j].BackColor = Color.White;
for (j = 0; j < 16; j++)
button[j].Text = "";
MessageBox.Show("Osvojili ste " + ukupno + " poena ! ! !", "Kraj igre");
label1.Text = "";
label1.BackColor = Color.DarkBlue;
}
int i;
private void button2_Click(object sender, EventArgs e)
{
i = 2;
}
private void button3_Click(object sender, EventArgs e)
{
i = 3;
}
private void button4_Click(object sender, EventArgs e)
{
i = 4;
}
private void button5_Click(object sender, EventArgs e)
{
i = 5;
}
private void button6_Click(object sender, EventArgs e)
{
i = 6;
}
private void button7_Click(object sender, EventArgs e)
{
i = 7;
}
private void button8_Click(object sender, EventArgs e)
{
i = 8;
}
private void button9_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button9, igra);
break;
case 2:
RacunajZaDugme(button2, button9, igra);
break;
case 3:
RacunajZaDugme(button3, button9, igra);
break;
case 4:
RacunajZaDugme(button4, button9, igra);
break;
case 5:
RacunajZaDugme(button5, button9, igra);
break;
case 6:
RacunajZaDugme(button6, button9, igra);
break;
case 7:
RacunajZaDugme(button7, button9, igra);
break;
case 8:
RacunajZaDugme(button8, button9, igra);
break;
}
}
private void button10_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button10, igra);
break;
case 2:
RacunajZaDugme(button2, button10, igra);
break;
case 3:
RacunajZaDugme(button3, button10, igra);
break;
case 4:
RacunajZaDugme(button4, button10, igra);
break;
case 5:
RacunajZaDugme(button5, button10, igra);
break;
case 6:
RacunajZaDugme(button6, button10, igra);
break;
case 7:
RacunajZaDugme(button7, button10, igra);
break;
case 8:
RacunajZaDugme(button8, button10, igra);
break;
}
}
private void button11_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button11, igra);
break;
case 2:
RacunajZaDugme(button2, button11, igra);
break;
case 3:
RacunajZaDugme(button3, button11, igra);
break;
case 4:
RacunajZaDugme(button4, button11, igra);
break;
case 5:
RacunajZaDugme(button5, button11, igra);
break;
case 6:
RacunajZaDugme(button6, button11, igra);
break;
case 7:
RacunajZaDugme(button7, button11, igra);
break;
case 8:
RacunajZaDugme(button8, button11, igra);
break;
}
}
private void button12_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button12, igra);
break;
case 2:
RacunajZaDugme(button2, button12, igra);
break;
case 3:
RacunajZaDugme(button3, button12, igra);
break;
case 4:
RacunajZaDugme(button4, button12, igra);
break;
case 5:
RacunajZaDugme(button5, button12, igra);
break;
case 6:
RacunajZaDugme(button6, button12, igra);
break;
case 7:
RacunajZaDugme(button7, button12, igra);
break;
case 8:
RacunajZaDugme(button8, button12, igra);
break;
}
}
private void button13_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button13, igra);
break;
case 2:
RacunajZaDugme(button2, button13, igra);
break;
case 3:
RacunajZaDugme(button3, button13, igra);
break;
case 4:
RacunajZaDugme(button4, button13, igra);
break;
case 5:
RacunajZaDugme(button5, button13, igra);
break;
case 6:
RacunajZaDugme(button6, button13, igra);
break;
case 7:
RacunajZaDugme(button7, button13, igra);
break;
case 8:
RacunajZaDugme(button8, button13, igra);
break;
}
}
private void button14_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button14, igra);
break;
case 2:
RacunajZaDugme(button2, button14, igra);
break;
case 3:
RacunajZaDugme(button3, button14, igra);
break;
case 4:
RacunajZaDugme(button4, button14, igra);
break;
case 5:
RacunajZaDugme(button5, button14, igra);
break;
case 6:
RacunajZaDugme(button6, button14, igra);
break;
case 7:
RacunajZaDugme(button7, button14, igra);
break;
case 8:
RacunajZaDugme(button8, button14, igra);
break;
}
}
private void button15_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button15, igra);
break;
case 2:
RacunajZaDugme(button2, button15, igra);
break;
case 3:
RacunajZaDugme(button3, button15, igra);
break;
case 4:
RacunajZaDugme(button4, button15, igra);
break;
case 5:
RacunajZaDugme(button5, button15, igra);
break;
case 6:
RacunajZaDugme(button6, button15, igra);
break;
case 7:
RacunajZaDugme(button7, button15, igra);
break;
case 8:
RacunajZaDugme(button8, button15, igra);
break;
}
}
private void button16_Click(object sender, EventArgs e)
{
switch (i)
{
case 1:
RacunajZaDugme(button1, button16, igra);
break;
case 2:
RacunajZaDugme(button2, button16, igra);
break;
case 3:
RacunajZaDugme(button3, button16, igra);
break;
case 4:
RacunajZaDugme(button4, button16, igra);
break;
case 5:
RacunajZaDugme(button5, button16, igra);
break;
case 6:
RacunajZaDugme(button6, button16, igra);
break;
case 7:
RacunajZaDugme(button7, button16, igra);
break;
case 8:
RacunajZaDugme(button8, button16, igra);
break;
}
}
private void button1_Click(object sender, EventArgs e)
{
i = 1;
}
}
}
|
|
|
|
|
I'm not reading that entire code dump. Most of is probably not related to the problem.
You can't randomly seek to a specific "line" in a text file. You have to read through it, looking for the lines that start with "*". You can do ignore a random number of them but you might want to initialize some structure with the data from the file, reading through the entire file looking for the "*" lines and recording which line you found it. You can then pick one at random, and get the line number to skip to. You have to go back re-read the file, counting lines until you get to the one you want.
When you get the line with the "*" in it, you start reading and recording the data from each line, these are your answers, until you get to another line with a "*" in it.
|
|
|
|
|
I would have approached this issue 'a bit differently' - it depends if you want to have to whole file in memory, or what you wish to optimise ...
Assuming you dont want the whole file in memory, you read the file multiple times
In the OnLoad event for the WinForm, I would fire off a Background thread, to parse the file to extract all the questions, their start lines in the file, the number of answers, to a data structure - possible an array of struct(string question, int start line, int num answers) - this is your 'index'
once you have a random number, you get that element from the index and use the start line and num answers to locate the answers in the file
If you can keep the entire set of data in memory, then you parse the file to something like array of struct(string question, List<string> answers), which means once you have your random number, you can jump straight to the index and get the question and answers
|
|
|
|
|
I would suggest that the best thing to do would be to change your file format.
If you used each line to hold a single question, together with it's possible answers, separated by '|' characters:
Planete i njihovi sateliti|Zemlja=Mesec|Mars=Fobos|Jupiter=Io|Saturn=Titan|Uran=Titania|Neptun=Triton|Pluton=Haron|Merkur=Nema satelit
Čuveni parovi iz umetnosti|Hamlet=Ofelija|Ruslan=Ljudmila|Zevs=Hera|Otelo=Dezdemona|Paris=Helena|Abelard=Eloiza|Paolo=Frančeska|Lanselot=Ginevra
...
Then the problem becomes trivial:
Use File.ReadAllLines to read the whole file into an array of strings: each element of the array is a question together with it's answers, so selecting a random question is a trivial use of the Random class.
Each question and answer can be easily split out into an array of strings using string.Split - the first element of the array is the question, the rest of them are possible answers.
But do yourself a favour: stop using Visual Studio default names for everything - you may remember that "TextBox8" is the mobile number today, but when you have to modify it in three weeks time, will you then? Use descriptive names - "tbMobileNo" for example - and your code becomes easier to read, more self documenting, easier to maintain - and surprisingly quicker to code because Intellisense can get to to "tbMobile" in three keystrokes, where "TextBox8" takes thinking about and 8 keystrokes...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
How to change format?
My text file has 15000 lines!!!!
|
|
|
|
|
Simple!
Write a quick app to do it for you. Something like this should do the donkey work:
private void ConvertFile(string inPath, string outPath)
{
string[] inData = File.ReadAllLines(inPath);
List<string> outData = new List<string>();
StringBuilder sb = new StringBuilder();
foreach (string line in inData)
{
if (line.StartsWith("*"))
{
if (sb.Length > 0)
{
outData.Add(sb.ToString());
sb.Clear();
}
sb.Append(line.Substring(1));
}
else
{
sb.Append("|");
sb.Append(line);
}
}
if (sb.Length > 0)
{
outData.Add(sb.ToString());
}
File.WriteAllLines(outPath, outData);
}
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I have added questions and answer to list!How to get random question with it's answers from the list?
string[] data = File.ReadAllLines("spojnice1.txt");
List<string> questions = new List<string>();
foreach (string line in data)
questions.Add(line);
|
|
|
|
|
You know the number of questions, so you should be easily able to use the Random class to pick the appropriate question. And I'm pretty sure that Griff recommended that you used a parent-child relationship so you added only the lines starting with * to the questions list, and then you would expose a list of answers as a child of the question.
This space for rent
|
|
|
|
|
He told me to change to this format text file:
Planete i njihovi sateliti|Zemlja=Mesec|Mars=Fobos|Jupiter=Io|Saturn=Titan|Uran=Titania|Neptun=Triton|Pluton=Haron|Merkur=Nema satelit
Čuveni parovi iz umetnosti|Hamlet=Ofelija|Ruslan=Ljudmila|Zevs=Hera|Otelo=Dezdemona|Paris=Helena|Abelard=Eloiza|Paolo=Frančeska|Lanselot=Ginevra
...
When I change to that format I cannot add lines starting with * to list!!!
|
|
|
|
|
Sigh. Let me simplify this for you.
Griff has suggested that you break your original list down (the ones that originally started with * being your question). These then have a number of answers stored as a series of pipe delimited fields. That's your parent/child relationship there.
The lines originally marked with * will now be the first entry in this pipe delimited list.
You know how many entries you have in this list, so you use this as the upper bound of the Random number.
That's it - the code is trivial. To make things more random, don't forget to seed the Random when you instantiate it. Read the documentation for details on how to do this.
This space for rent
|
|
|
|
|
Hi,
if the majority of your application needs to know the file structure, then something is definitely wrong.
At the minimum you should define data structures that reflect the problem domain, read your file once, and stuff all the info into the data structures, then work from there.
However, I would also consider using a database; from what I understood you would need two tables: one for questions, one for the remaining info; and an N-to-1 relationship between them.
|
|
|
|
|
Hi all,
I am using Selenium ver 2.53.0, Firefox 46.0.1. I want to create an application that use Selenium WebDriver to do parallel tasks. I have created an app like that but: My app opened 2 webdrivers and its task was the same, not different task as I have assigned to each thread before. I wonder what was going on? Was there one-one connection between thread 1 - Webdriver 1 AND thread 2 - Webdriver 2 OR not? If not I suggest each thread was pushing its data to active Webdriver at that time. Was I right?
Hope to get any help from all of you, so I can solve my issue. Thank you!
Best Regards,
Sokhanh
|
|
|
|
|
You don't provide the correct information to diagnose your problem.
But I will say that WebDriver is not thread-safe. You can't have multiple threads using the same WebDriver instance.
You CAN, however, have each thread create it's own instance of WebDriver, but each one of those is going to create it's own instance of the browser. This is going to greatly increase the amount of memory your app is using.
|
|
|
|
|