how can I try to run two methods simultaneously at each intervals of time in c#,
I tried with timer and task but the method is firing and it is not displaying.
( there is two data table, it should run simultaneously each other )
method in page load event()
protected void Page_Load(object sender, EventArgs e)
{
object value = null;
Thread thread = new Thread(() => { value = method(); });
thread.Start();
thread.Join();
PlaceHolder1.Controls.Add(new Literal { Text = value.ToString() });
Thread.Sleep(600);
Thread thread2 = new Thread(() => { value = NewMethod(); });
thread2.Start();
thread2.Join();
PlaceHolder1.Controls.Add(new Literal { Text = value.ToString() });
Thread.Sleep(600);
}
Related
I have a button that starts two threads
private void CrawdBtn_Click(object sender, EventArgs e)
{
CrawdBtn.Enabled = false;
t = new Thread(AddLinksToList);
b = new Thread(EnqueueFromList);
t.Start();
b.Start();
}
and there are another buttons to pause, Resume, Stop those threads
My question is how can I disable (pause, Resume, Stop) buttons while the threads are working and re enable Crawl after the threads finished
Here is how you could start a Thread and have a way to await its completion:
public static Thread CreateAwaitableThread(Action action, out Task threadCompletion)
{
var tcs = new TaskCompletionSource<bool>();
threadCompletion = tcs.Task;
return new Thread(() =>
{
try
{
action();
}
finally
{
tcs.SetResult(true);
}
});
}
This method returns the newly created Thread, and also a Task that will be completed when the Thread is completed. You could use it like this:
private async void CrawdBtn_Click(object sender, EventArgs e)
{
CrawdBtn.Enabled = false;
Thread t1 = CreateAwaitableThread(AddLinksToList, out var t1c);
Thread t2 = CreateAwaitableThread(EnqueueFromList, out var t2c);
t1.Start();
t2.Start();
await Task.WhenAll(t1c, t2c);
CrawdBtn.Enabled = true;
}
In case of an exception the error will not be propagated through the Task. It is assumed that the delegates already include error handling logic. If not, an unhandled exception will occur as usual.
To solve your problem you can make a thread to check the ThreadState of thread t and thread b
private void btnstart_Click(object sender, EventArgs e)
{
t = new Thread(AddLinksToList);
b = new Thread(EnqueueFromList);
t.Start();
b.Start();
if (threadchecker == null)//this if determines Whether it's the first time or not
{
threadchecker = new Thread(() => ChekingStateOfThreads());
threadchecker.IsBackground = true;
threadchecker.Start();
}
}
Since the thread wants to check the ThreadState of those threads it should always run.
and This is ChekingStateOfThreads
private void ChekingStateOfThreads()
{
while (true)
{
Thread.Sleep(1000);
if (t.ThreadState == ThreadState.Stopped)
{
this.Invoke(new Action(() =>
{
btnpause.Enabled = btnstart.Enabled = false;
btnresume.Enabled = btnstop.Enabled = true;
}));
}
else if (t.ThreadState == ThreadState.Running)
{
this.Invoke(new Action(() =>
{
btnstart.Enabled = btnresume.Enabled = false;
btnpause.Enabled = btnstop.Enabled = true;
}));
}
else if (t.ThreadState == ThreadState.Aborted)
{
this.Invoke(new Action(() =>
{
btnstart.Enabled = true;
btnpause.Enabled = btnresume.Enabled = btnstop.Enabled = false;
}));
}
else if (t.ThreadState == ThreadState.Suspended)
{
this.Invoke(new Action(() =>
{
btnpause.Enabled = btnstart.Enabled = false;
btnresume.Enabled = btnstop.Enabled = true;
}));
}
}
}
The concept of function is pretty simple. Each 1 second the thread is check the state of thread t.
See Why use Invoke on Controls in .net? to figure out why should we use INVOKE.
To abort the threadchecker just use the Form_closing Event
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
threadchecker.Abort();
}
I have looked everywhere for the answer and I thought it would be simple to find but apparently not. I've heard about invoke but I have no idea how to use it or what it is.
Here is my code:
public void Thread1(object sender, EventArgs e)
{
this.button1.Enabled = false;
this.textBox2.Clear();
this.textBox3.Clear();
this.textBox4.Clear();
this.textBox6.Text = "£" + "0";
//Generate 3 random numbers
Stopwatch timer = new Stopwatch();
timer.Start();
this.Refresh();
//This is only part of this function
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart threadStart = new ThreadStart(() => Thread1(sender, e));
Thread newThread = new Thread(threadStart);
newThread.Start();
}
In background threads, use Invoke() on WinForms components to execute code on the UI thread:
this.Invoke( () => {
this.button1.Enabled = true;
this.textBox2.Text = "whatever";
} );
Documentation: https://msdn.microsoft.com/en-us/library/a1hetckb.aspx
I hav tried the below code for checking reports from server in every 30seconds,but after 30seconds tick,The application hangs for several seconds.How to avoid the Hanging problem.
The below code am tried,what change want to given in this?
System.Windows.Threading.DispatcherTimer dispatcherTimer2 = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer2.Tick += new EventHandler(dispatcherTimer2_Tick);
dispatcherTimer2.Interval = new TimeSpan(0, 0, 30);
Public void dispatcherTimer2_Tick(object sender, EventArgs e)
{
dispatcherTimer2.start();
//code for function call autoreport();
}
DispatcherTimer callback is executed on main UI thread and blocks it.
Use System.Threading.Timer and if you need to update user interface from timer callback use one of
Dispatcher.Invoke
overloads.
In code something like this
public partial class MainWindow : Window
{
System.Threading.Timer timer;
public MainWindow()
{
InitializeComponent();
timer = new System.Threading.Timer(OnCallBack, null, 0, 30 * 1000);
}
private void OnCallBack(object state)
{
//code to check report
Dispatcher.Invoke(() =>
{
//code to update ui
this.Label.Content = string.Format("Fired at {0}", DateTime.Now);
});
}
}
var timer = new System.Threading.Timer(
delegate
{
//--update functions here (large operations)
var value = Environment.TickCount;
//--run update using interface thread(UI Thread)
//--for WinForms
Invoke(
new Action(() =>
{
//--set the value to UI Element
}));
//--for WPF
Dispatcher.Invoke(
new Action(() =>
{
//--set the value to UI Element
}), null);
});
var period = TimeSpan.FromSeconds(30);
timer.Change(period, period);
I hope it helps.
This is worked for me
public Form1()
{
InitializeComponent();
var timer = new System.Timers.Timer(500);
// Hook up the Elapsed event for the timer.
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Invoke(
new Action(() =>
{
label1.Text += "Test Label";
Application.DoEvents();
}));
}
I think the title speaks for itself. Simply I have some threads that run with a random order instead of the order I planned.
This is a sample code:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
strChanged += new strHandler(updatestr);
}
public void updatestr(string str)
{
Thread th = new Thread(new ParameterizedThreadStart(updatethr));
th.IsBackground = true;
th.Start(str);
}
object obj = new object();
private void updatethr(object str)
{
lock (obj)
{
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}
Note: SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) is a function (used to avoid cross thread exception) that set textBox1.Text to str.
When you press button1 this.Text will be set instantly to the result of write() function ("012345").
The string returned is res that is build inside write() starting from an empty string and, iteratively, appending numbers from 0 to 5.
When the string is created and for each number added to res, the event strChanged is raised calling updatestr method.
Every time that updatestr is called a thread is created and it starts calling updatethr.
Here textBox1.Text is set to str (that should be progressively "", "0" , "01", "012", "0123", "01234", "012345") and wait a second before exiting the method.
Using lock statement the threads created in updatestr should wait the end of the previous threads before modifying textBox1.Text.
Running this code I obtain sequences of values for textBox1.Text that don't match the expected sequence as if the threads don't start in order with their creation in updatestr.
Why does this happen? How can I fix that? Thanks in advance!
EDIT: If want to try this code you can replace SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) with System.Windows.Forms.MessageBox.Show(str)
I believe you are looking for a different threading strategy. It appears you need a single thread, to maintain order, that's different from the Form's main thread to finish an operation. By using a BlockingCollection, you can sequentially have a different thread operate on the string.
I would rewrite the code this way:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(updatethr));
th.IsBackground = true;
th.Start();
strChanged += new strHandler(updatestr);
}
BlockingCollection<string> bc = new BlockingCollection<string>();
public void updatestr(string str)
{
bc.Add(str);
}
private void updatethr()
{
while(true)
{
string str = bc.Take();
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
// Not sure why you need this here, other than simulating a long operation.
// Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}
I'm beginner in C#. And i have problem with threads when i using win.forms. My application freezes. What the problem with this code? I'm using microsoft example from msdn.
Here's my code:
delegate void SetTextCallback(object text);
private void WriteString(object text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(WriteString);
this.Invoke(d, new object[] { text });
}
else
{
for (int i = 0; i <= 1000; i++)
{
this.textBox1.Text = text.ToString();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Thread th_1 = new Thread(WriteString);
Thread th_2 = new Thread(WriteString);
Thread th_3 = new Thread(WriteString);
Thread th_4 = new Thread(WriteString);
th_1.Priority = ThreadPriority.Highest; // самый высокий
th_2.Priority = ThreadPriority.BelowNormal; // выше среднего
th_3.Priority = ThreadPriority.Normal; // средний
th_4.Priority = ThreadPriority.Lowest; // низкий
th_1.Start("1");
th_2.Start("2");
th_3.Start("3");
th_4.Start("4");
th_1.Join();
th_2.Join();
th_3.Join();
th_4.Join();
}
There is a deadlock - UI thread is waiting for threads to complete with Thread.Join() while the worker threads are trying to send a message to UI using blocking Control.Invoke(). Replacing the Invoke in the thread code by BeginInvoke() will make the deadlock go away
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(WriteString);
// BeginInvoke posts message to UI thread asyncronously
this.BeginInvoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text.ToString();
}
It freezes because of the Join calls. Thread.Join() makes the current thread wait after another one is complete.