loop use async or thread instead of timer - c#

Sorry for my little English
I have a problem
Instead of the timer, I need to run the codes below in a loop.
can you help me with this
my main purpose
to use thread or async
if (NumbersIndexCounter != PhoneNumbersList.Count)
{
SendMessage(PhoneNumbersList[NumbersIndexCounter++]);
}
lblFailedProcess.Text = FailedProcess.ToString();
lblSuccedProcess.Text = SuccedProcess.ToString();
//metroLabel2.Text = toplamprocess.ToString();
Thread.Sleep(2000);
dataGridİnfos.DataSource = "";
dataGridİnfos.DataSource = InfoList;
Thread.Sleep(Convert.ToInt16(txtWaitBeforeEveryMessage.Text)*1000);
ProcessCounter++;
if (NumbersIndexCounter == PhoneNumbersList.Count)
{
int s1, s2;
s1 = Convert.ToInt32(lblFailedProcess.Text);
s2 = Convert.ToInt32(lblSuccedProcess.Text);
int toplam = s1 + s2;
metroLabel2.Text = "Toplam = " + toplam;
timer1.Stop();
Driver.Quit();
MessageBox.Show("Bitti!");
NumbersIndexCounter = 0;
grpBxMessage.Enabled = true;
grpBxPhoneNumbers.Enabled = true;
grpBxSettings.Enabled = true;
PhoneNumbersList.Clear();
}
if (ProcessCounter == Convert.ToInt32(txtMessageCountForWait.Text))
{
Thread.Sleep(Convert.ToInt16(txtWait.Text) * 1000);
ProcessCounter = 0;
}
but when I use a private void in my codes, it works once and does not continue. When I use a timer, it works without any problems, but the form is not response.

Related

How to scroll down while page loading - GeckoFx C#

I want to scroll down while a page loading in geckofx 45.
I tried to to do with following code, but it seems not to work.
wb.Navigate("javascript: var s = function() { window.scrollBy(550, 10000); }; s();");
How is that possible?
int scrollTo = 30;
public void scrollDown()
{
this.wb.Focus();
string result = string.Empty;
AutoJSContext context;
string jsScript = string.Empty;
try
{
if (scrollTo > 100)
{
scrollTo = 5;
}
context = new AutoJSContext(this.wb.Window);
jsScript = "var x = document.getElementsByClassName('ANY_ELEMENTS_CLASS_NAME'); x[" + (scrollTo * 2) + "].scrollIntoView(); ";// CHANGE ANY_ELEMENTS_CLASS_NAME
context.EvaluateScript(jsScript, (nsISupports)wb.Window.DomWindow, out result);
scrollTo += 5;
}
catch (Exception e)
{
}
}
this helped me

C# Decoding X10 Code

I like to decode X10 Code on the Raspberry Pi using C# on Windows 10 IoT but I haven no experience with RF decoding, so this is new territory for me.
I came across this post and I tried to convert this into C# code, but I had no success. Does anyone know how to decode this X10 Code correctly using C#, or can someone point me to the right Protocol specifications.
Here is the code I am currently using, however the ValueChanged Event is not called.
public static void Sniff(uint gpioPinNumb)
{
Task.Run(() => {
using (GpioPin pin = GpioController.GetDefault().OpenPin((int)gpioPinNumb, GpioSharingMode.Exclusive))
{
pin.SetDriveMode(GpioPinDriveMode.Input);
Stopwatch sw = Stopwatch.StartNew();
long elapsedMicrons = 0;
int[] states = new int[67];
int[] durations = new int[67];
uint changeCount = 0;
bool lockPassed = false;
bool isLock = false;
pin.ValueChanged += (GpioPin sender, GpioPinValueChangedEventArgs args) =>
{
elapsedMicrons = sw.ElapsedTicks / 10;
sw.Restart();
//Debug.WriteLine(elapsedMicrons);
if (elapsedMicrons > 25000 && !lockPassed && !isLock)
{
//X10 lock started
changeCount = 0;
durations[changeCount++] = (int)elapsedMicrons;
isLock = true;
Debug.WriteLine("Lock Started");
Debug.WriteLine("");
}
else if (isLock)
{
if (changeCount >= durations.Length)
{
isLock = false;
changeCount = 0;
Debug.WriteLine("===============================");
for (int i = 0; i < durations.Length; i++)
{
Debug.Write(durations[i++]);
Debug.Write(" ");
}
Debug.WriteLine("");
}
else
{
durations[changeCount++] = (int)elapsedMicrons;
}
}
};
}
});
}
Here is the code I am currently using, however the ValueChanged Event
is not called.
This issue caused by using statement that the C# "using" statement results in a call to Dispose(). This is the same as Close(). It also causes the object itself to go out of scope as soon as Dispose is called.
For safety you can move pin out of Sniff method like this:
private static GpioPin pin;
public static void Sniff(uint gpioPinNumb)
{
Task.Run(() => {
pin = GpioController.GetDefault().OpenPin((int)gpioPinNumb, GpioSharingMode.Exclusive);
pin.SetDriveMode(GpioPinDriveMode.Input);
...
...

write file out of memory c#

I get some problems with c# windows form.
My goal is to slice a big file(maybe>5GB) into files,and each file contains a million lines.
According to the code below,I have no idea why it will be out of memory.
Thanks.
StreamReader readfile = new StreamReader(...);
StreamWriter writefile = new StreamWriter(...);
string content;
while ((content = readfile.ReadLine()) != null)
{
writefile.Write(content + "\r\n");
i++;
if (i % 1000000 == 0)
{
index++;
writefile.Close();
writefile.Dispose();
writefile = new StreamWriter(...);
}
label5.Text = i.ToString();
label5.Update();
}
The error is probably in the
label5.Text = i.ToString();
label5.Update();
just to make a test I've written something like:
for (int i = 0; i < int.MaxValue; i++)
{
label1.Text = i.ToString();
label1.Update();
}
The app freezes around 16000-18000 (Windows 7 Pro SP1 x64, the app running both x86 and x64).
What probably happens is that by running your long operation in the main thread of the app, you stall the message queue of the window, and at a certain point it freezes. You can see that this is the problem by adding a
Application.DoEvents();
instead of the
label5.Update();
But even this is a false solution. The correct solution is moving the copying on another thread and updating the control every x milliseconds, using the Invoke method (because you are on a secondary thread),
For example:
public void Copy(string source, string dest)
{
const int updateMilliseconds = 100;
int index = 0;
int i = 0;
StreamWriter writefile = null;
try
{
using (StreamReader readfile = new StreamReader(source))
{
writefile = new StreamWriter(dest + index);
// Initial value "back in time". Forces initial update
int milliseconds = unchecked(Environment.TickCount - updateMilliseconds);
string content;
while ((content = readfile.ReadLine()) != null)
{
writefile.Write(content);
writefile.Write("\r\n"); // Splitted to remove a string concatenation
i++;
if (i % 1000000 == 0)
{
index++;
writefile.Dispose();
writefile = new StreamWriter(dest + index);
// Force update
milliseconds = unchecked(milliseconds - updateMilliseconds);
}
int milliseconds2 = Environment.TickCount;
int diff = unchecked(milliseconds2 - milliseconds);
if (diff >= updateMilliseconds)
{
milliseconds = milliseconds2;
Invoke((Action)(() => label5.Text = string.Format("File {0}, line {1}", index, i)));
}
}
}
}
finally
{
if (writefile != null)
{
writefile.Dispose();
}
}
// Last update
Invoke((Action)(() => label5.Text = string.Format("File {0}, line {1} Finished", index, i)));
}
and call it with:
var thread = new Thread(() => Copy(#"C:\Temp\lst.txt", #"C:\Temp\output"));
thread.Start();
Note how it will write the label5 every 100 milliseconds, plus once at the beginning (by setting the initial value of milliseconds "back in time"), each time the output file is changed (by setting the value of milliseconds "back in time") and after having disposed everything.
An even more correct example can be written by using the BackgroundWorker class, that exists explicitly for this scenario. It has an event, ProgressChanged, that can be subscribed to update the window.
Something like this:
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerAsync(new string[] { #"C:\Temp\lst.txt", #"C:\Temp\output" });
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
string[] arguments = (string[])e.Argument;
string source = arguments[0];
string dest = arguments[1];
const int updateMilliseconds = 100;
int index = 0;
int i = 0;
StreamWriter writefile = null;
try
{
using (StreamReader readfile = new StreamReader(source))
{
writefile = new StreamWriter(dest + index);
// Initial value "back in time". Forces initial update
int milliseconds = unchecked(Environment.TickCount - updateMilliseconds);
string content;
while ((content = readfile.ReadLine()) != null)
{
writefile.Write(content);
writefile.Write("\r\n"); // Splitted to remove a string concatenation
i++;
if (i % 1000000 == 0)
{
index++;
writefile.Dispose();
writefile = new StreamWriter(dest + index);
// Force update
milliseconds = unchecked(milliseconds - updateMilliseconds);
}
int milliseconds2 = Environment.TickCount;
int diff = unchecked(milliseconds2 - milliseconds);
if (diff >= updateMilliseconds)
{
milliseconds = milliseconds2;
worker.ReportProgress(0, new int[] { index, i });
}
}
}
}
finally
{
if (writefile != null)
{
writefile.Dispose();
}
}
// For the RunWorkerCompleted
e.Result = new int[] { index, i };
}
void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int[] state = (int[])e.UserState;
label5.Text = string.Format("File {0}, line {1}", state[0], state[1]);
}
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
int[] state = (int[])e.Result;
label5.Text = string.Format("File {0}, line {1} Finished", state[0], state[1]);
}

Thread program, 1st and last loop never has a ThreadedState other than 'Running'

I have a programming that is looping x times (10), and using a specified number of threads (2). I'm using a thread array:
Thread[] myThreadArray = new Thread[2];
My loop counter, I believe, starts the first 2 threads just fine, but when it gets to loop 3, which goes back to thread 0 (zero-based), it hangs. The weird thing is, if I throw a MessageBox.Show() in their to check the ThreadState (which shows thread 0 is still running), it will continue on through 9 of the 10 loops. But if no MessageBox.Show() is there, it hangs when starting the 3rd loop.
I'm using .NET 3.5 Framework (I noticed that .NET 4.0 utilizes something called continuations...)
Here's some code examples:
Thread[] threads = new Thread[2];
int threadCounter = 0;
for (int counter = 0; counter < 10; counter++)
{
if (chkUseThreading.Checked)
{
TestRunResult runResult = new TestRunResult(counter + 1);
TestInfo tInfo = new TestInfo(conn, comm, runResult);
if (threads[threadCounter] != null)
{
// If this is here, then it will continue looping....otherwise, it hangs on the 3rd loop
MessageBox.Show(threads[threadCounter].ThreadState.ToString());
while (threads[threadCounter].IsAlive || threads[threadCounter].ThreadState == ThreadState.Running)
Thread.Sleep(1);
threads[threadCounter] = null;
}
// ExecuteTest is a non-static method
threads[threadCounter] = new Thread(new ThreadStart(delegate { ExecuteTest(tInfo); }));
threads[threadCounter].Name = "PerformanceTest" + (counter + 1);
try
{
threads[threadCounter].Start();
if ((threadCounter + 1) == threadCount)
threadCounter = 0;
else
threadCounter++;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Application.DoEvents();
}
}
while (true)
{
int threadsFinished = 0;
for (int counter = 0; counter < threadCount; counter++)
{
if (!threads[counter].IsAlive || threads[counter].ThreadState == ThreadState.Stopped)
threadsFinished++;
}
if (threadsFinished == threadCount)
break;
else
Thread.Sleep(1);
}
Obviously the problem is something about how I'm checking to see if thread #1 or #2 is done. The IsAlive always says true, and the ThreadState always has "running" for threads loops 1 and 10.
Where am I going wrong with this?
Update, here's the ExecuteTask() method:
private void ExecuteTest(object tInfo)
{
TestInfo testInfo = tInfo as TestInfo;
Exception error = null;
DateTime endTime;
TimeSpan duration;
DateTime startTime = DateTime.Now;
try
{
if (testInfo.Connection.State != ConnectionState.Open)
{
testInfo.Connection.ConnectionString = connString;
testInfo.Connection.Open();
}
testInfo.Command.ExecuteScalar();
}
catch (Exception ex)
{
error = ex;
failedCounter++;
//if (chkCancelOnError.Checked)
// break;
}
finally
{
endTime = DateTime.Now;
duration = endTime - startTime;
RunTimes.Add(duration);
testInfo.Result.StartTime = startTime;
testInfo.Result.EndTime = endTime;
testInfo.Result.Duration = duration;
testInfo.Result.Error = error;
TestResults.Add(testInfo.Result);
// This part must be threadsafe...
if (lvResults.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(ExecuteTest);
this.Invoke(d, new object[] { tInfo });
}
else
{
lvResults.Items.Add(testInfo.Result.ConvertToListViewItem());
#region Update Results - This wouldn't work in it's own method in the threaded version
const string msPrefix = "ms";
// ShortestRun
TimeSpan shortest = GetShortestRun(RunTimes);
tbShortestRun.Text = shortest.TotalMilliseconds + msPrefix;
// AverageRun
TimeSpan average = GetAverageRun(RunTimes);
tbAverageRun.Text = average.TotalMilliseconds + msPrefix;
// MeanRun
TimeSpan mean = GetMeanRun(RunTimes);
tbMeanRun.Text = mean.TotalMilliseconds + msPrefix;
// LongestRun
TimeSpan longest = GetLongestRun(RunTimes);
tbLongestRun.Text = longest.TotalMilliseconds + msPrefix;
// ErrorCount
int errorCount = GetErrorCount(TestResults);
tbErrorCount.Text = errorCount.ToString();
#endregion
}
testInfo.Command.Dispose();
Application.DoEvents();
}
}
Can you post a snippet of run ()? Doesn't Thread.currentThread().notifyAll() help? May be each thread is waiting for other thread to do something resulting in a deadlock?

Console animations

I just want to know how to create simple animations like blinking, moving stuffs on C# console applications. Is there any special method for this?
Traditional Console Spinner:
static void Main(string[] args)
{
ConsoleSpiner spin = new ConsoleSpiner();
Console.Write("Working....");
while (true)
{
spin.Turn();
}
}
public class ConsoleSpiner
{
int counter;
public ConsoleSpiner()
{
counter = 0;
}
public void Turn()
{
counter++;
switch (counter % 4)
{
case 0: Console.Write("/"); break;
case 1: Console.Write("-"); break;
case 2: Console.Write("\\"); break;
case 3: Console.Write("|"); break;
}
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
Here is my spinner. The purpose of it is to have a program do some work while the spinner displays to the user that something is actually happening:
public class Spinner : IDisposable
{
private const string Sequence = #"/-\|";
private int counter = 0;
private readonly int left;
private readonly int top;
private readonly int delay;
private bool active;
private readonly Thread thread;
public Spinner(int left, int top, int delay = 100)
{
this.left = left;
this.top = top;
this.delay = delay;
thread = new Thread(Spin);
}
public void Start()
{
active = true;
if (!thread.IsAlive)
thread.Start();
}
public void Stop()
{
active = false;
Draw(' ');
}
private void Spin()
{
while (active)
{
Turn();
Thread.Sleep(delay);
}
}
private void Draw(char c)
{
Console.SetCursorPosition(left, top);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(c);
}
private void Turn()
{
Draw(Sequence[++counter % Sequence.Length]);
}
public void Dispose()
{
Stop();
}
}
And you use the class like this:
using (var spinner = new Spinner(10, 10))
{
spinner.Start();
// Do your work here instead of sleeping...
Thread.Sleep(10000);
}
Yes, there are quite a few methods for this.
In particular, you may want to look at the following Console methods:
SetCursorPosition (you can move the cursor around, and overwrite elements)
MoveBufferArea (copy/paste over the top of regions)
ForegroundColor and BackgroundColor (change coloring)
Great work with the ConsoleSpinner and the sequence implementation. Thanks for the code. I thought about sharing my customized approach.
public class ConsoleSpinner
{
static string[,] sequence = null;
public int Delay { get; set; } = 200;
int totalSequences = 0;
int counter;
public ConsoleSpinner()
{
counter = 0;
sequence = new string[,] {
{ "/", "-", "\\", "|" },
{ ".", "o", "0", "o" },
{ "+", "x","+","x" },
{ "V", "<", "^", ">" },
{ ". ", ".. ", "... ", "...." },
{ "=> ", "==> ", "===> ", "====>" },
// ADD YOUR OWN CREATIVE SEQUENCE HERE IF YOU LIKE
};
totalSequences = sequence.GetLength(0);
}
/// <summary>
///
/// </summary>
/// <param name="sequenceCode"> 0 | 1 | 2 |3 | 4 | 5 </param>
public void Turn(string displayMsg = "", int sequenceCode = 0)
{
counter++;
Thread.Sleep(Delay);
sequenceCode = sequenceCode > totalSequences - 1 ? 0 : sequenceCode;
int counterValue = counter % 4;
string fullMessage = displayMsg + sequence[sequenceCode, counterValue];
int msglength = fullMessage.Length;
Console.Write(fullMessage);
Console.SetCursorPosition(Console.CursorLeft - msglength, Console.CursorTop);
}
}
Implementation:
ConsoleSpinner spinner = new ConsoleSpinner();
spinner.Delay = 300;
while (true)
{
spinner.Turn(displayMsg: "Working ",sequenceCode:5);
}
Output:
You'll need to use Console.ForegroundColor, Console.BackgroundColor and Console.SetCursorPosition(int, int)
EDIT: For inspiration, Let's Dance
Just saw this and a few other threads about it and love this kind of stuff! I took Tuukka's nice piece of code and improved it a bit so the class can easily be set to just about any spin sequence. I'll probably add some accessors and an overloaded constructor to polish it off and put it in the ol' toolbox. Fun stuff!
class ConsoleSpinner
{
int counter;
string[] sequence;
public ConsoleSpinner()
{
counter = 0;
sequence = new string[] { "/", "-", "\\", "|" };
sequence = new string[] { ".", "o", "0", "o"};
sequence = new string[] { "+", "x" };
sequence = new string[] { "V", "<", "^", ">" };
sequence = new string[] { ". ", ".. ", "... ", "...." };
}
public void Turn()
{
counter++;
if (counter >= sequence.Length)
counter = 0;
Console.Write(sequence[counter]);
Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop);
}
}
I took the anwser from #ThisGuy and modified it a bit, but I noticed, that sometimes the row is not cleared as it should.
static void Main(string[] args)
{
Console.WriteLine("1");
var tddf = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd 4343", () =>
{
return "";
});
Console.WriteLine("2");
var tdd = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd", () =>
{
Thread.Sleep(1);
return "";
});
Console.WriteLine("3");
var t = XConsole.BusyIndicator("test 1 trtg vdgd", () =>
{
Thread.Sleep(1000);
return "";
});
Console.WriteLine("4");
var xt = XConsole.BusyIndicator("test 2", () =>
{
Thread.Sleep(2000);
return "";
});
var xtx = XConsole.BusyIndicator("test 2 csds fsd fdsf ds s", () =>
{
Thread.Sleep(2000);
return "";
});
Console.WriteLine("5");
Thread.Sleep(4000);
}
Spinner class:
public class Spinner : IDisposable
{
private const string Sequence1 = #"/-\|";
private const string Sequence3 = #".o0o";
private const string Sequence2 = #"<^>v";
private const string Sequence4 = #"#■.";
private const string Sequence5 = #"▄▀";
private const string Sequence = #"└┘┐┌";
private string BusyMessage = "";
private int counter = 0;
private readonly int delay;
private bool active;
private readonly Thread thread;
public Spinner(int delay = 200)
{
this.delay = delay;
thread = new Thread(Spin);
}
public void Start()
{
active = true;
Console.CursorVisible = false;
if (!thread.IsAlive)
{
thread.Start();
}
}
public void Start(string busyMessage)
{
BusyMessage = busyMessage;
Start();
}
public void Stop()
{
active = false;
Console.CursorVisible = true;
ClearCurrentConsoleLine();
BusyMessage = "";
}
private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
private void Spin()
{
while (active)
{
Turn();
Thread.Sleep(delay);
}
}
/// <summary>
/// Draws the busy indicator
/// </summary>
/// <param name="c">if empty char, then clear screen</param>
private void Draw(char c)
{
int left = Console.CursorLeft;
int top = Console.CursorTop;
Console.Write('[');
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(c);
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(']');
if (!string.IsNullOrEmpty(BusyMessage))
{
Console.Write(" " + BusyMessage);
}
//reset cursor position
Console.SetCursorPosition(left, top);
}
private void Turn()
{
Draw(Sequence[++counter % Sequence.Length]);
}
public void Dispose()
{
Stop();
}
}
My console class:
public static class XConsole {
public static T BusyIndicator<T>(Func<T> action)
{
T result;
using (var spinner = new Spinner())
{
spinner.Start();
result = action();
spinner.Stop();
}
return result;
}
public static T BusyIndicator<T>(string content, Func<T> action)
{
T result;
using (var spinner = new Spinner())
{
spinner.Start(content);
result = action();
spinner.Stop();
}
return result;
}
}
Why do I see this result sometimes?
1
2
3 st 0 trtg fdfdfvdgd ]
4
[└] test 2 csds fsd fdsf ds s
Looks like the Dispose didn't trigger? Or a new Task alredy started?
It should look like this:
1
2
3
4
[└] test 2 csds fsd fdsf ds s
UPDATE:
I added ClearCurrentConsoleLine(); and changed the Draw method, this fixed the issue.
i'm not TOO sure i know exactly what you're on about. but i'll give it a shot.
I think the biggest and best way to cause the "blinking" affect (or what i think the blinking affect is) is to use a carriage return.
The best way to explain it to you is to show you the Foo Bar experiment.
start a new project, and in your Main function, try this.
Console.WriteLine("Foo/nBar");
The output will look like this
Foo
Bar
But if you use a carriage return.
Console.WriteLine("Foo/rBar");
The output will look like this
Bar
The reason is that Foo is written, then the carriage return takes you BACK to the start of the line, then Bar is written. All you ever see is Bar.
This can be helpful for "Moving" things on one line, instead of rewriting the same things again on multiple lines.
A way to do progression would be to use Console.Write();
Try this.
Console.Write("Loading");
for(int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.Write(".");
}
The output should be
Loading
Followed by a Fullstop every second for 10 seconds.
If you combine the Carriage return with the Console.Write(); function you can write multiple things on a single line, clear the line and write something else, or indeed, the same thing just moved slightly. (This would of course need more than i have shown you, like recording where the "object" you are controlling is situated. If you would like a short example i would be happy to do one, just comment and ask me for it :)
Edit:
I noticed people mentioning colour, which i forgot. If you were doing animation i guess colour would be a must.
ForegroundColor and BackgroundColor are where it's at.
note that ForegroundColor will apply to the next characters written to the console, it will not completely recolour the Console.
/Edit
I hope this helps,
Skintkingle ;)
I thought I'd chime in with my version of the previously listed code. Here it is:
class ConsoleSpinner
{
bool increment = true,
loop = false;
int counter = 0;
int delay;
string[] sequence;
public ConsoleSpinner(string sSequence = "dots", int iDelay = 100, bool bLoop = false)
{
delay = iDelay;
if (sSequence == "dots")
{
sequence = new string[] { ". ", ".. ", "... ", "...." };
loop = true;
}
else if (sSequence == "slashes")
sequence = new string[] { "/", "-", "\\", "|" };
else if (sSequence == "circles")
sequence = new string[] { ".", "o", "0", "o" };
else if (sSequence == "crosses")
sequence = new string[] { "+", "x" };
else if (sSequence == "arrows")
sequence = new string[] { "V", "<", "^", ">" };
}
public void Turn()
{
if (loop)
{
if (counter >= sequence.Length - 1)
increment = false;
if (counter <= 0)
increment = true;
if (increment)
counter++;
else if (!increment)
counter--;
}
else
{
counter++;
if (counter >= sequence.Length)
counter = 0;
}
Console.Write(sequence[counter]);
Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop);
System.Threading.Thread.Sleep(delay);
}
}
Adds delay (unfortunately through Thread.Sleep() but, hey), the ability to loop the animation forwards and backwards (starts to reverse when it hits the end), and general improvements overall. Enjoy!
This would be my prefered method:
public sealed class Spinner
{
private static Lazy<Spinner> lazy =
new Lazy<Spinner>(()=> new Spinner());
public static void Reset()
{
lazy = new Lazy<Spinner>(()=> new Spinner());
}
public static Spinner Instance { get { return lazy.Value; }}
private readonly int _consoleX;
private readonly int _consoleY;
private readonly char[] _frames = { '|', '/', '-', '\\' };
private int _current;
private Spinner()
{
_current = 0;
_consoleX = Console.CursorLeft;
_consoleY = Console.CursorTop;
}
public void Update()
{
Console.Write(_frames[_current]);
Console.SetCursorPosition(_consoleX, _consoleY);
if (++_current >= _frames.Length)
_current = 0;
}
}
Call Spinner.Instance.Update() to start the spinner at the current position of the console. Any consecutive call will render the next frame at the same position.
Call Spinner.Reset() if you want to write more text and then add a new spinner at a new location.
This is the way i solved it, sure it could/can be shorter but, Im just not that smart yet :-)
void cc() { Console.Clear(); }
void cr() { Console.ReadKey(); }
byte Sleeptimer = 90;
void sleepy() { System.Threading.Thread.Sleep(Sleeptimer); }
string[] Loading = { #"-- ", #"\ ", #"| ", #"/ ", "Loading", " complete!" };
for (byte i = 0; i <= 15; i++)
{
cc();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(Loading[0] + Loading[4]);
sleepy();
cc();
Console.WriteLine(Loading[1] + Loading[4]);
sleepy();
cc();
Console.WriteLine(Loading[2] + Loading[4]);
sleepy();
cc();
Console.WriteLine(Loading[3] + Loading[4]);
sleepy();
cc();
if (i == 15) {
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(Loading[4] + Loading[5]);
cc();
Console.ForegroundColor = ConsoleColor.Cyan;
Next();
}
}
/*
Now i feel even more noob while reading your code.
I'm a newbie in programing.
Guess this way would work if i just incfement the index of each Loading down below right?
Learned too much today, forgot how this exactly works, to increment or to change the index i'd lile to acces
Console.WriteLine(Loading[2] + Loading[4]);
sleepy();
cc();
*/
This is animation with cancellationToken
private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
public static async Task Start(CancellationToken ct)
{
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine();
string text = "Executing";
for (int i = 0; i <= 3; i++)
{
if (ct.IsCancellationRequested)
{
Console.SetCursorPosition(0, Console.CursorTop - 1);
ClearCurrentConsoleLine();
ct.ThrowIfCancellationRequested();
}
Thread.Sleep(1000);
Console.SetCursorPosition(0, Console.CursorTop - 1);
ClearCurrentConsoleLine();
Console.WriteLine(text);
if (i == 3)
{
text = "Executing";
i = 0;
}
text += ".";
}
});
}```

Categories