How to stop the Console from pausing my Threads and Tasks? - c#

When I am using the scrollbar in the console window all Threads and Tasks are getting paused. Are there any ways to prevent that from happening?
example:
Task.Run(async () =>
{
for (var z = 0; true; z++)
{
Console.WriteLine(z);
await Task.Delay(200);
}
});
or
var s = new Thread(() =>
{
for (var z = 0; true; z++)
{
Console.WriteLine(z);
Thread.Sleep(200);
}
});
If you run either one of these code samples as a console application, both will do the same: print some numbers. During execution hold the scrollbar with your left mouse button for some time and the numbers will stop coming up. The Task/Thread has been paused. When you release the mouse button the numbers will continue.
Because the number after the release of the scroll bar follows the one before, the console has not simply stopped the output of the numbers. It has been waiting in the Console.WriteLine - method until a am releasing the scroll bar.
Does anyone know how to fix my problem?

There is not much you can do to stop this. Console.WriteLine will block while you are holding down your scroll bar, this has nothing to do with threads or tasks at all. The following small program shows the same issue.
using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
for (var z = 0; true; z++)
{
Console.WriteLine(z);
Thread.Sleep(200);
}
}
}
}
You can't change the behavior of Console.WriteLine the only thing you can do is put a buffer between you and the writes to the console.
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//The writer lives in another thread.
var s = new Thread(ConsoleWriter);
s.Start();
for (var z = 0; true; z++)
{
//This add call does not get blocked when Console.WriteLine gets blocked.
LinesToWrite.Add(z.ToString());
Thread.Sleep(200);
}
}
static void ConsoleWriter()
{
foreach (var line in LinesToWrite.GetConsumingEnumerable())
{
//This will get blocked while you hold down the scroll bar but
// when you let go it will quickly catch up.
Console.WriteLine(line);
}
}
static readonly BlockingCollection<string> LinesToWrite = new BlockingCollection<string>();
}
}
This is only a quick and dirty solution to this, there are other ways of solving this to make it more transparent like making a class derived from TextWriter that will buffer the calls and using that class in a call to Console.SetOut(.

You'll need to asynchronously write to the console if you don't want the code to block when access to the console is locked (in this case, by the user), and not wait for that asynchronous operation to finish before continuing on. This can be done as simply as using Task.Run(() => Console.WriteLine(z)) in place of Console.WriteLine(z).
You'll also need to make a copy (before the call to Run) of any closed over variables that will end up being mutated after the call to Task.Run, since closures close over variables rather than values.
That said, it's a strong indication that you should re-consider your design here. Perhaps the console isn't the right way for you to output your data; another type of UI may be appropriate.

Related

How Can i Print 2 Works by threads side by side in same column in c# Console?

So Here is the Program Again
As u can see i have Created 2 methods with a Working Loop
And Created 2 threads in main pointing towards these methods and they are started
What gets out as output is Both Loops work like 1 and then space and in new line 1 and so on
But what i want is to make them appear in the same row line side by side As we divide a page in 2 parts and write things in lines
I do not want To make them Work Seperately but at a time and in the same line but Different columns
I know it can be acheived by Writing Both Objects in same Console .wl but i want to acheive it this way by these 2 threads
Please provide valuable solutions that would work
Thanks
using System;
using System.Threading;
class Program
{
static void Main(string [] args)
{
Thread t1 = new Thread(code1);
Thread t2= new Thread (code2);
t1.Start();
t2.Start();
}
static void code1()
{
for(int i=0;i<50;i++)
{
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
static void code2()
{
for(int i=0;i<50;i++)
{
Console.WriteLine("/t/t"+i);
Thread.Sleep(1000);
}
}}
You have to use the Console.SetCursorPosition(int left, int top) method, so you can write on the Console starting from any position you want, also back in the previous rows.
Obviously, you have to keep trace of the position for each Thread. That is, the current row of that Thread, and its first column.
In my example I made 2 threads, one with the first column in position 0, and the second with the first column in position 50. Be careful about the width of the strings that you need to write, or they will overflow their own space on the Console.
Also, because you are doing it in a multithreading app, you need a lock on the Console. Otherwise, suppose this: a Thread sets the CursorPosition, then another Thread sets it, then the scheduler returns to the first Thread... the first Thread writes on the second Thread's position!
This is a very simple Console Program that gets the point:
using System;
using System.Threading;
namespace StackOverflow_3_multithread_on_console
{
class Program
{
static Random _random = new Random();
static void Main(string[] args)
{
var t1 = new Thread(Run1);
var t2 = new Thread(Run2);
t1.Start();
t2.Start();
}
static void Run1()
{
for(int i = 0; i < 30; i++)
{
Thread.Sleep(_random.Next(2000)); //for test
ConsoleLocker.Write("t1:" + i.ToString(), 0, i);
}
}
static void Run2()
{
for (int i = 0; i < 30; i++)
{
Thread.Sleep(_random.Next(2000)); //for test
ConsoleLocker.Write("t2:" + i.ToString(), 30, i);
}
}
}
static class ConsoleLocker
{
private static object _lock = new object();
public static void Write(string s, int left, int top)
{
lock (_lock)
{
Console.SetCursorPosition(left, top);
Thread.Sleep(100); //for test
Console.Write(s);
}
}
}
}
All the Thread.Sleep are there just to demonstrate that the lock works well. You can remove all them, especially the one in the ConsoleLocker.

Semaphore halting my thread

My code below halts on the semaphore.
Code creates the thread correctly. It runs correctly when the semaphore code is removed.
How do I make my semaphore block the code section, this case is just a loop, then release the semaphore when the loop is done.
lock
loop
un-lock
actual code here:
using System.IO;
using System;
using System.Threading;
public class Program
{
public static Semaphore sema;
static void Main()
{
sema = new Semaphore(0, 2);
Work w = new Work();
Thread t = new Thread(w.doWork);
t.Start(null);
}
}
public class Work
{
public void doWork(object data)
{
Program.sema.WaitOne();
for(int i = 0; i < 10; i++)
Console.WriteLine("I made it");
Program.sema.Release();
}
}
The semaphore is initially closed because there are no free slots available. There must be some free before you are able to cross the WaitOne() call.
sema = new Semaphore(0, 2);
This is allowing 0 enters, you need to modify 0 to the number of concurrent access you want to allow.

Multithreading BlockingCollection same value

I am using two threads in a C# application that access the same BlockingCollection. This works fine, but I want to retrieve the first value twice so the two threads retrieve the same value *.
After a few seconds I want to poll the currentIndex of both threads and delete every value < index. So for example the lowest currentIndex of a thread is 5, the application deletes theitems at index 0 -5 in the queue. Another solution is to delete the value in the queue if all threads processed the value.
How can I accomplish this? I think I need another type of buffer..?
Thank you in advance!
*If .Take() is called by thread1, the item is removed in the collection and thread2 can't get the same item again.
Update:
I want to store data in a buffer, so for example thread1 saves the data to a HDD and thread2 analyzes the (same) data (concurrent).
Use a producer-consumer to add Value1 to two separate ConcurrentQueues. Have the threads dequeue then process them from their own queue.
Edit 7/4/14:
Here's a, hazy, hacky, and half thought out solution: Create a custom object that is buffered. It could include space for both the information you're trying to buffer in thread 1 and the analysis results in thread 2.
Add the objects to a buffer in thread 1 and a BlockingCollection. Use thread 2 to analyse the results and update the objects with the results. The blocking collection shouldn't get too big, and since it's only dealing with references shouldn't hit your memory. This assumes that you won't be modifying the info in the buffer at the same time on both threads.
Another, also half thought out solution is to feed the info into the buffer and a blocking collection simultaneously. Analyse the data from the BlockingCollection, feed it into an output collection and match them up with the buffer again. This option can handle concurrent modification if you do it right, but is probably more work.
I think option one is better. As I've pointed out, these are only half-formed, but they might help you find something that suits your specific needs. Good luck.
I would suggest to rethink your design.
When you have a list of items which have to processed then give each thread a queue of items which he have to work on.
With such a solution it wouldn't be a problem to give both or more threads the same value to process.
Something like this, not tested just typed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections.Concurrent;
namespace ConsoleApplication2
{
class Item
{
private int _value;
public int Value
{
get
{
return _value;
}
}
// all you need
public Item(int i)
{
_value = i;
}
}
class WorkerParameters
{
public ConcurrentQueue<Item> Items = new ConcurrentQueue<Item>();
}
class Worker
{
private Thread _thread;
private WorkerParameters _params = new WorkerParameters();
public void EnqueueItem(Item item)
{
_params.Items.Enqueue(item);
}
public void Start()
{
_thread = new Thread(new ParameterizedThreadStart(ThreadProc));
_thread.Start();
}
public void Stop()
{
// build somthing to stop your thread
}
public static void ThreadProc(object threadParams)
{
WorkerParameters p = (WorkerParameters)threadParams;
while (true)
{
while (p.Items.Count > 0)
{
Item item = null;
p.Items.TryDequeue(out item);
if (item != null)
{
// do something
}
}
System.Threading.Thread.Sleep(50);
}
}
}
class Program
{
static void Main(string[] args)
{
Worker w1 = new Worker();
Worker w2 = new Worker();
w1.Start();
w2.Start();
List<Item> itemsToProcess = new List<Item>();
for (int i = 1; i < 1000; i++)
{
itemsToProcess.Add(new Item(i));
}
for (int i = 1; i < 1000; i++)
{
w1.EnqueueItem(itemsToProcess[i]);
w2.EnqueueItem(itemsToProcess[i]);
}
}
}
}

pausing program without interrupting timers c#

I am writing a program that has several "Worker" objects going off and doing tasks that take as set amount of time. I have created a worker class with an internal timer that is working fine. However, when doing the "work" i will at times need to wait several seconds for a screen refresh (each worker is scraping data from a remote screen and doing some automation).
For those pauses, i don't want to sleep the thread, because as i understand it that will also
pause the timers on the other worker objects (my application is a single thread because, frankly, I'm brand new to C# and i didn't want to overreach). Is there another waiting function that i can use that doesn't actually hang the whole thread?
Some additional info:
Right now this is a console app, but i will eventually be building a UI form to provide feedback to the user on how the workers are doing
My timers are implemented using System.Timers and are working quite nicely
I am brand new to C# programming, this is my first project, so please use small words ;)
Using MS VS Express 2012 for Desktop (so whatever version of C# / .NET that is!)
Code below (the actual work will be done using the "startWorking" method, but nothing is implemented - this is just my sold build with timers working. Also, the main is just being used for testing multiple timers right now)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace Multi_Timers
{
//worker class that includes a timer
public class Worker
{
private Timer taskTimer;
private bool available = true;
private string workerName;
private string startWork;
private int workTime;
// properties
public bool isAvailable { get { return this.available; } }
public string name { get { return this.workerName; } }
// constructor
public Worker(string name)
{
this.workerName = name;
Console.WriteLine("{0} is initialized", name);
}
// start work timer
public void startWorking(int duration) {
if (this.available == true)
{
this.available = false;
this.taskTimer = new Timer();
this.taskTimer.Interval = duration;
this.taskTimer.Elapsed += new ElapsedEventHandler(doneWorking);
this.taskTimer.Enabled = true;
this.startWork = DateTime.Now.ToString();
this.workTime = duration / 1000;
}
else Console.WriteLine("Sorry, {0} was not available to work", this.workerName);
}
// Handler for timer
public void doneWorking(object sender, ElapsedEventArgs e)
{
Console.WriteLine("{0}: {1} / {2} min / {3}", this.workerName, this.startWork, this.workTime/60, e.SignalTime.ToLocalTime());
this.taskTimer.Enabled = false;
this.available = true;
}
}
//main program
class Program
{
static void Main(string[] args)
{
Random r = new Random();
// initialize worker(s)
Worker bob = new Worker("Bob");
Worker bill = new Worker("Bill");
Worker jim = new Worker("Jim");
// q to exit
while (true)
{
if (bob.isAvailable) {
bob.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
if (bill.isAvailable)
{
bill.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
if (jim.isAvailable)
{
jim.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
}
}
}
}
Thank you for any help in advance! Reading examples from this community was definitely key in teaching myself a little bit of C# to get started with!
i don't want to sleep the thread, because as i understand it that will also pause the timers on the other worker objects
That is incorrect; it will not stop the timers.
my application is a single thread
No, actually, it's not. The timers will be creating and using other threads to implement their behavior. The Elapsed event handlers will be fired from a thread pool thread.
One major issue with your code is that your main method is doing a "busywait" on the three objects, constantly polling them asking if they're done. This is...expensive. It's basically like you're kids asking, "Are we there yet." a few hundred times a second. Wouldn't it be so much nicer if they just sat their waiting until you told them you were done! (That's quite possible, and a good possible option.)
One of the simpler solutions in this case would be to do the loop in the worker, not Main. Have the implementation of startWorking wrapped in a while loop, and have main just do a wait forever (i.e. Thread.Sleep(Timeout.Infinite);). More complex options would be having the workers provide a Task, event, or blocking wait (also called a "Join") method to indicate when they are finished.
The option you're considering, that of adding a Thread.Sleep of a little while in Main will help, but it's only telling your kids to ask you when you're there less often, rather than having them wait for you to tell them when you're there.
If you ever find yourself wanting to delay execution again in a different context you could consider an implementation like this:
private static void DelayExecution(Action action, TimeSpan delay)
{
TimeSpan start = DateTime.Now.TimeOfDay;
Thread t = new Thread(() =>
{
while (DateTime.Now.TimeOfDay < start.Add(delay))
{
//Block
}
action.Invoke();
});
t.Start();
}
private static void Main(string[] args)
{
DelayExecution(() => Console.WriteLine("Delayed Execution"), TimeSpan.FromSeconds(1));
Console.ReadLine();
}

MultiThreading inside Loop and Wait Threads WinForms and C#

I'm in trouble with this code. I'm using .Net (C#) with Winform Application.
I need to run RunProgram Method which has loop that make a call to a method named ListLoop.
In this function there is a forach that creates 1 thread for each element a list.
(Please Read the code before continue to read the description so you could understand what i'm talking about )
The problem is that if i dont make any control in the "for" (RunProgram Method) it starts (of course) 10 times The ListLoop Function.
So i would add in that "For" a code which wait that all Threads are terminated, so i can do Something and Then continue with the next loop.
I tried thread.join() but it freeze my UI application
(it's Application which inside has a WebControl Browser).
Even if i Try to play with returnThred and with thread.isAlive it still freezes UI.
If i hadn't the Multithread i'll dont stay here with those problems but it's the only good solution for my program i think.
Is there a simple solution for my code?
Update: Maybe it'snt clear my question.
I just want run the ListLoop X times but before start the next one i want wait that all threads are dead (That ones of the first call) so i can do some control and continue with the loop inside RunProgram.
Update2 I have this UI application which has a WebBrowser Control. I have a List of Links Object (each element of this class has string url and idHost =1 2 3 4...1 for google 2 for yahoo etc...)
I want make a loop where my program start a newTab (with Method AddTab(url) ) for each element of the list. When all links are opened (and so all the threads are deads and) i need to do something that count how many pages opened and who was the idHost save it and start another Loop with the list(This list take random element from a Bigger List)
Update 3 I just tried with BackGround Worker but i cant use it cause the WebKit that i'm using give COM error. Something for the Tasks.
Thanks
private void RunProgram()
{
List<Links> TheList = new List<Links>();
//Do something to Populate the List
List<System.Threading.Thread> returnThread = new List<.....>();
for(int i=0; i<10; i++)
{
returnThread=ListLoop(TheList);
// ???????????
// When Loop Method has finished and all threads stopped
// Do something
// Continue for the next Loop
}
}
private List<System.Threading.Thread> ListLoop(List<Links> list)
{
List<System.Threading.Thread> threading = new List<System.Threading.Thread>();
foreach (Links link in list)
{
Links tmp = new Links();
tmp = link;
var thread = new System.Threading.Thread(p =>
{
lock (l)
{
Action action = () =>
{
AddTab(tmp);
};
this.Invoke(action);
if (tmp.idHost == 1) //if IDhost == Google wait 5sec
{
System.Threading.Thread.Sleep(5000);
}
else
{
System.Threading.Thread.Sleep(2000);
}
}
});
threading.Add(thread);
thread.Start();
}
return threading;
}
If RunProgram is called from your main application, it will freeze your main form if it sleeps or waits for threads to terminate. You should run the RunProgram method in its own thread, so it can then create the worker threads, and then you can wait for the threads to complete in your for loop before starting new ones.
You could use AutoResetEvent to signal when threads are finished so you can simply wait on the AutoResetEvent before continuing the loop. The BackgroundWorker class may be a good class to look at for creating your threads as well.
I'm not sure if I understood your question properly, but:
You work asynchronously here... You can't wait in your code without stopping the GUI.
I think your solution will be to separate your function into 2 parts - The 1st one you just written, and the second one works after the threads are all dead.
For the second part (check the threads) I'd use either another thread (That waits until the threads are dead than continues to your code) or a Timer if you'd like to save threads and integrate easily into the main form
UPDATE:
Here is an example of how a blocking function that doesn't block the GUI thread:
using System.Windows.Forms;
using System.Threading;
using System;
namespace Threads
{
public partial class Form1 : Form
{
public event EventHandler OnSomethingFinishes;
public Form1()
{
InitializeComponent();
OnSomethingFinishes += new EventHandler(Form1_OnSomethingFinishes);
}
void Form1_OnSomethingFinishes(object sender, EventArgs e)
{
this.Invoke(new EventHandler(Form1_OnSomethingFinishesSafe), sender, e);
}
void Form1_OnSomethingFinishesSafe(object sender, EventArgs e)
{
this.Text = "Done!";
}
private void BlockingFunction(object a_oParameter)
{
// Do something that blocks
Thread.Sleep(2000);
if (OnSomethingFinishes != null)
OnSomethingFinishes(this, null);
}
private void button1_Click(object sender, EventArgs e)
{
Thread l_oThread = new Thread(BlockingFunction);
l_oThread.Start();
this.Text = "Please Wait...";
}
}
}
button1 starts the process. Notice that you have to invoke the function after the event is handled to move the control to the main GUI thread
Hope this helps

Categories