Pause song for 10 seconds then start playing - c#

Working on a Valentines gift for my wife and I wanted the mp3 song to start to play after 10 seconds. What I have works but for some reason it starts right away and I can't figure out why.
for (int x = 1; x < 20; x++)//60
{
switch (x)
{
case 19://59
mplayerlevel2.URL = "All of you John Legend.mp3";
break;
default:
break;
}
}

You can set a Task to execute in the future and then keep executing your program in the meantime.
Task
.Delay(TimeSpan.FromSeconds(10))
.GetAwaiter()
.OnCompleted(() =>
{
mplayerlevel2.URL = "All of you John Legend.mp3";
});

Assuming WinForms and a Button Click event, put async in the method signature and use await Task.Delay():
private async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
await Task.Delay(10000);
mplayerlevel2.URL = "All of you John Legend.mp3";
button1.Enabled = true;
}
From your further comments:
I wanted to have a screen showing an animated heart and then a few
seconds later it will play that song
I think you'd better off with a TIMER set to 10 seconds. You can put your animated GIF in a PictureBox (it'll animate on its own when the form opens), then in the Tick() event of the Timer, start your music:
public partial class Form1 : Form
{
private System.Windows.Forms.Timer tmr;
public Form1()
{
InitializeComponent();
tmr = new System.Windows.Forms.Timer();
tmr.Interval = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
tmr.Tick += Tmr_Tick;
tmr.Start();
}
private void Tmr_Tick(object sender, EventArgs e)
{
tmr.Stop();
mplayerlevel2.URL = "All of you John Legend.mp3";
}
}
You could alternatively drop the Timer from your ToolBox onto your form and set it up that way instead of creating it through code as I have done.

i'd use a native sleep function, which is made for this :
System.Threading.Thread.Sleep(10000);

Related

Textbox not displaying text and UI screen not moving

This is my requirement I have to use while loop inside timer, after launch application after click on button UI is locked not able to move and text is not diplaying at textbox too
below is the code
using System;
using System.Windows.Forms;
namespace WinScreenLocked
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int Number = 0;
private void timer1_Tick(object sender, EventArgs e)
{
while (true)
{
textBox1.Text = Number.ToString();
Number++;
}
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
}
}
// Create a 30 min timer
timer = new System.Timers.Timer(1800000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// do stuff
}
with the usual caveats of: timer won't be hugely accurate and might need to GC.KeepAlive(timer)
See also: Why does a System.Timers.Timer survive GC but not System.Threading.Timer?
you can stop the thread to block the ui i.e using
System.Threading.Thread.Sleep(2000);
it takes miliseconds in above 2000 miliseconds is equal to 2 seconds.
Seeing as this is winforms you can use Application.DoEvents() to process the UI refresh.
See this : https://social.msdn.microsoft.com/Forums/en-US/b1b1969d-8a51-496c-9274-a0ac1708a8b4/what-does-applicationdoevents-actually-do?forum=csharplanguage

c# Fill textbox while listbox is being filled

This is my code:
private void _1_Load(object sender, EventArgs e)
{
FillA();
FillB();
// Tried these lines too but they show listbox values but not textbox value
// var t2 = Task.Run(() => FillA());
// FillB();
}
private void FillA()
{
this.Invoke(new MethodInvoker(delegate()
{
for (int i = 1; i > 0; i++)
{
listBox1.Items.Add(i.ToString());
listBox1.Update();
Thread.Sleep(25);
}
}));
}
private void FillB()
{
Thread.Sleep(3000); //1 seconds delay
textBox1.Text = "Hello World!";
}
When the page loads the listbox should starts showing the number 1, 2, 3... and then after few seconds of delay the textbox should show the Hello World! value but the listbox should keep growing. How do I ensure that first the listbox should start filling and then the textbox should fill. I don't want to wait for the filling of the listbox and then textbox to be filled.
Any advice would be appreciated.
Edit:
This is just a sample code. In actual production there would be two processes and the second process will start once the first process is started fetching data and storing in listbox.
The first process should keep on going. I can't stop it in middle as it would create inconsistency in the data.
Don't use Sleep. Instead use Timer-class:
https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx
Configure a timeout of 1s.
Hook up the Elapsed event for the timer:
aTimer.Elapsed += OnTimedEvent;
In method OnTimedEvent you can increment a integer-variable i.
Depending on value of i you fill first listbox and if value is higher fill the other Listbox.
You cannot add all items at once to the listbox and update the textbox in between as these operations are done synchronously in WindowsForms.
Instead you should add only a subset of items to the listbox, update the textbox and then continue adding items to the listbox.
To not freeze the GUI in between waiting for operations, you can use async\await combination instead of Thread.Sleep().
private async void _1_Load(object sender, EventArgs e)
{
await AddInitialListBoxItems();
await FillTextBox();
await AddRemainingListBoxItems();
}
private async Task AddInitialListBoxItems()
{
for (int i = 1; i < 10; i++)
{
listBox1.Items.Add(i.ToString());
listBox1.Update();
await Task.Delay(25);
}
}
private async Task FillTextBox()
{
await Task.Delay(3000); //1 seconds delay
textBox1.Text = "Hello World!";
}
private async Task AddRemainingListBoxItems()
{
for (int i = 11; i < 100; i++)
{
listBox1.Items.Add(i.ToString());
listBox1.Update();
await Task.Delay(25);
}
}
If you can use Timers instead of direct threading, this might help you. It worked on my pc:
Edit since you need the textbox to get written after some delay, you need to use a timer for it as well. I have edited the code below. Textbox is written after 1 seconds of listbox population starting.
public partial class Form1 : Form
{
int counter = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 25;
timer.Tick += Timer_Tick;
timer.Start();
System.Windows.Forms.Timer timerTextbox = new System.Windows.Forms.Timer();
timerTextbox.Interval = 1000;
timerTextbox.Tick += TimerTextbox_Tick; ;
timerTextbox.Start();
}
private void TimerTextbox_Tick(object sender, EventArgs e)
{
FillB();
(sender as System.Windows.Forms.Timer).Stop();
}
private void Timer_Tick(object sender, EventArgs e)
{
listBox1.Items.Add(counter.ToString());
counter++;
listBox1.Update();
}
private void FillB()
{
textBox1.Text = "Hello World!";
}
}
Of course when you call Thread.Sleep(3000); //1 seconds delay on Load event (3000 ms is 3 seconds btw), your form will be shown 3 seconds late.

setText in textbox with infinite loop

I am writing activity recognition software in realtime. But i can't setText in textbox with infinite loop. I try to search Google but no answer. When, i using "textbox.Text += "ZZZZ", it working but I using "textbox.Text = "ZZZ" ", it not working. I hope someone can point me how to solve
private void button1_Click(object sender, EventArgs e)
{
for (; ; ){
Thread.Sleep(20);
........process....
tb_activity = "AAA";
}
}
You can use the new await and async feature in .Net:
private void button1_Click(object sender, EventArgs e)
{
EndlessTask();
}
async Task EndlessTask()
{
for(int i = 0; true; i++)
{
textBox1.Text = i.ToString();
await Task.Delay(500);
}
}
[Edit] Note, if you want to get rid of the async warning:
#pragma warning disable 4014
EndlessTask();
#pragma warning restore 4014
i can't setText in textbox with infinite loop
you can never confirm that un till unless you debug your application while using the Thread.Sleep() in infinite loop.
Reason: when you use Thread.Sleep() it makes your Main thread to sleep so it is not a good practice to use Thread.Sleep() . it hangs your UI therefore you can not see the Control Updates on the UI like Label Text update ,TextBox Text Update things like that.
ofcourse you call Application.DoEvents() to refresh the UI but it is not a good practice as there are many other problems.
Solution: i suggest you to use Timer instead of using Thread.Sleep() as it runs in the background so it doesnot hang your UI and also you can see the updates on UI.
Simple Example to show you how to use Timer for updating the Text on Textbox # certain intervals
public partial class Form1 : Form
{
int count = 0;
string text1 = "this is a scrolling text";
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
textBox1.ReadOnly = true;
SetTimer(500);
}
private void SetTimer(int milliseconds)
{
timer1.Tick+=new EventHandler(timer1_Tick);
timer1.Interval = milliseconds;
timer1.Start();
}
private void timer1_Tick(Object o, EventArgs e)
{
if (count < text1.Length)
{
textBox1.Text += text1[count];
count++;
}
else
{
timer1.Stop();
button1.Enabled = true;
textBox1.ReadOnly = false;
}
}
}

Simple Timer in C#

I have this code
private void picTop_MouseEnter(object sender, EventArgs e)
{
if (timer1.Tick == 10)
{
picBottom.Visible = true;
picTop.Visible = false;
timer1.Stop();
}
else
{
MessageBox.Show("ERROR You cannot view this section at this time.\nPlease try again later.");
}
}
private void picBottom_MouseEnter(object sender, EventArgs e)
{
picBottom.Visible = false;
picTop.Visible = true;
timer1.Start();
}
My timerinterval is set at 1000ms (so 1 second)
I only want the user to go into the top panel again after 10 seconds.
Some help would be greatly appreciated.
Current error I get: timer1.Tick is red underlined, error=
"The event 'System.Windows.Forms.Timer.Tick' can only appear on the left hand side of += or -="
Timer.Tick is not property its an event.
Use it like
timer1.Tick +=
{
picBottom.Visible = true;
picTop.Visible = false;
timer1.Stop();
}
For interval use timer.Interval
timer.Interval = 10000;
Ok. I think I understand what you're trying to achieve...
You have 2 areas on your form called "Top" & "Bottom"
Once the user enters & subsequently leaves the top area, you don't want them to be able to enter again for 10 seconds. is that correct?
So you've got a few problems... first of all, Tick is an event to which you would attach a method to be fired when it is raised. it's not an integer you can check. The only integer property on a timer of relevance for timing for is called Interval
But aside from that I don't think your method is going to be particularly effective.
Perhaps a better idea would be to add a MouseExit event to the top area. and disable that area for 10 seconds. and use a timer to re-enable it.
timer1.Tick += timer1_Tick;
public void Top_MouseExit (object sender, EventArgs e)
{
PicTop.Visible = false; // or hide/disbale it some other way
Timer1.Interval = 10000; //10 seconds
Timer1.Start();
}
public void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
PicTop.Visible = true; //renable the top area
}

C# Simple Countdown - What am I doing wrong?

I wanted to make a simple Countdown-Application with C# to show as an example.
For the very first and basic version I use a Label to display the current time left in seconds and a Button to start the countdown. The Button's Click-Event is implemented like this:
private void ButtonStart_Click(object sender, RoutedEventArgs e)
{
_time = 60;
while (_time > 0)
{
_time--;
this.labelTime.Content = _time + "s";
System.Threading.Thread.Sleep(1000);
}
}
Now when the user clicks the Button the time is actually counted down (as the application freezes (due to Sleep())) for the chosen amount of time but the Label's context is not refreshed.
Am I doing something generally wrong (when it comes to Threads) or is it just a problem with the UI?
Thank you for your answers!
I now use a System.Windows.Threading.DispatcherTimer to do as you told me. Everything works fine so this question is officially answered ;)
For those who are interested: Here is my code (the essential parts)
public partial class WindowCountdown : Window
{
private int _time;
private DispatcherTimer _countdownTimer;
public WindowCountdown()
{
InitializeComponent();
_countdownTimer = new DispatcherTimer();
_countdownTimer.Interval = new TimeSpan(0,0,1);
_countdownTimer.Tick += new EventHandler(CountdownTimerStep);
}
private void ButtonStart_Click(object sender, RoutedEventArgs e)
{
_time = 10;
_countdownTimer.Start();
}
private void CountdownTimerStep(object sender, EventArgs e)
{
if (_time > 0)
{
_time--;
this.labelTime.Content = _time + "s";
}
else
_countdownTimer.Stop();
}
}
Yes, event handlers should not block - they should return immediately.
You should implement this by a Timer, BackgroundWorker or Thread (in this order of preference).
What you are seeing is the effect of a long-running message blocking the windows message queue/pump - which you more commonly associate with the white application screen and "not responding". Basically, if your thread is sleeping, it isn't responding to messages like "paint yourself". You need to make your change and yield control to the pump.
There are various ways of doing this (ripper234 does a good job of listing them). The bad way you'll often see is:
{ // your count/sleep loop
// bad code - don't do this:
Application.DoEvents();
System.Threading.Thread.Sleep(1000);
}
I mention this only to highlight what not to do; this causes a lot of problems with "re-entrancy" and general code management. A better way is simply to use a Timer, or for more complex code, a BackgroundWorker. Something like:
using System;
using System.Windows.Forms;
class MyForm : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
Timer timer;
MyForm() {
timer = new Timer();
count = 10;
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
protected override void Dispose(bool disposing) {
if (disposing) {
timer.Dispose();
}
base.Dispose(disposing);
}
int count;
void timer_Tick(object sender, EventArgs e) {
Text = "Wait for " + count + " seconds...";
count--;
if (count == 0)
{
timer.Stop();
}
}
}

Categories

Resources