How can I run the code below in LinqPad as C# Program Thank you...
class ThreadTest
{
static void Main()
{
Thread t = new Thread (WriteY); // Kick off a new thread
t.Start(); // running WriteY()
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++) Console.Write ("x");
}
static void WriteY()
{
for (int i = 0; i < 1000; i++) Console.Write ("y");
}
}
Result Expected
xxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
So far I came up with
static void Main()
{
Thread t = new Thread (ThreadTest.WriteY); // Kick off a new thread
t.Start(); // running WriteY()
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++) Console.Write ("x");
}
class ThreadTest
{
public static void WriteY()
{
for (int i = 0; i < 1000; i++) Console.Write ("y");
}
}
Actual Result
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy...
As seen on Result Expected it should be mixed X and Y.
Unfortunately Actual Result is 1000 times X and 1000 times Y
UPDATE
This sample - along with all the others in the concurrency chapters of C# 5 in a Nutshell are downloadable as a LINQPad sample library. Go to LINQPad's samples TreeView and click 'Download/Import more samples' and choose the first listing. – Joe Albahari
Thread switching is by nature non-deterministic. I can run your program multiple times and get varying results.
If you want the switching to be more evident, add some pauses:
static void Main()
{
Thread t = new Thread (ThreadTest.WriteY); // Kick off a new thread
t.Start(); // running WriteY()
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++)
{
Console.Write ("x");
Thread.Sleep(1);
}
}
class ThreadTest
{
public static void WriteY()
{
for (int i = 0; i < 1000; i++)
{
Console.Write ("y");
Thread.Sleep(1);
}
}
}
I cannot explain why this works, but changing to using Dump() seems to make it behave like the OP wants with the x's and y's "mixed" with every run (although with newlines between every output):
void Main()
{
Thread t = new Thread (ThreadTest.WriteY); // Kick off a new thread
t.Start(); // running WriteY()
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++) "x".Dump();
}
class ThreadTest
{
public static void WriteY()
{
for (int i = 0; i < 1000; i++) "y".Dump();
}
}
From the LinqPAD documentation:
LINQPad's Dump command feeds the output into an XHTML stream which it
displays using an embedded web browser (you can see this by
right-clicking a query result and choosing 'View Source'. The
transformation into XHTML is done entirely using LINQ to XML, as one
big LINQ query! The deferred expansion of results works via
JavaScript, which means the XHTML is fully prepopulated after a query
finishes executing. The lambda window populates using a custom
expression tree visitor (simply calling ToString on an expression tree
is no good because it puts the entire output on one line).
I also know that LinqPAD overrides the default Console.WriteLine behavior, so perhaps that has something to do with it.
Related
i add a loop to my program just to check something...(For verification)
for (int i = 1; i < total; i++){
for (int row = 0; row < 4; row++){
for (int col = 0; col < 4; col++){
pixel = block[i][row][col];
label1.Text = pixel.R.ToString("X");
System.Threading.Thread.Sleep(100);}}}
After Add this loop program works , but form doesnt show up. I Start Debuging and i saw that in this line it stops. Dont go any further.
Application.Run(new Form1());
Basicly begining of the program. So I isolate the System.Threading.Thread.Sleep(100);}}}
Part it is working now. Why this code is causing problem. I used the
using System.Threading.Tasks;.
Any idea or i can use other delay function... İ waiting for your help. Thank you..
You should never, ever, block the UI Thread (by means of sleeping or doing some heavy work) as the Thread can only either handle UI-Events (clicks, rerendering, resizing) or run your code, not both. In cases where you must execute some long running code from a event-handler, you can either start a new thread to do the work or run async code.
For you, something like this should work just fine:
public async void Form1_Load(object sender, EventArgs e) {
for (int i = 1; i < total; i++){
for (int row = 0; row < 4; row++){
for (int col = 0; col < 4; col++){
pixel = block[i][row][col];
label1.Text = pixel.R.ToString("X");
await Task.Delay();
}
}
}
}
While Sleep blocks the thread while it waits, await Task.Delay(); does not. It actually returns and lets the thread continue doing whatever it was doing previously and notifies the thread when it finished waiting so the thread can come back to your function later and continue running your code. (This is a simplification of how async and await works in C#)
I'm running into a sync issue involving reporting progress inside of a Parallel.ForEach. I recreated a simplified version of the problem in a Console App. The example actually only uses one item in the list. Here's the code:
class Program
{
static void Main(string[] args)
{
int tracker = 0;
Parallel.ForEach(Enumerable.Range(1, 1), (item) =>
{
var progress = new Progress<int>((p) =>
{
tracker = p;
Console.WriteLine(String.Format("{0}", p));
});
Test(progress);
});
Console.WriteLine("The last value is: {0}", tracker);
Console.ReadKey();
}
static void Test(IProgress<int> progress)
{
for (int i = 0; i < 20; i++)
{
progress.Report(i);
}
}
}
As you can see, the line I expect to see last isn't output last and doesn't contain 20. But if I remove progress reporting and just write to output in the for loop like this:
class Program
{
static void Main(string[] args)
{
int tracker = 0;
Parallel.ForEach(Enumerable.Range(1, 1), (item) =>
{
tracker = Test();
});
Console.WriteLine("The last value is: {0}", tracker);
Console.ReadKey();
}
static int Test()
{
int i;
for ( i = 0; i < 20; i++)
{
Console.WriteLine(i.ToString());
}
return i;
}
}
it behaves like I expect. As far as I know, Parallel.ForEach creates a Task for each in item in the list and IProgress captures the context in which it's created on. Given it's a console app I didn't think that would matter. Help please!
The explanation is pretty much exactly what's written in the docs:
Any handler provided to the constructor or event handlers registered with the ProgressChanged event are invoked through a SynchronizationContext instance captured when the instance is constructed. If there is no current SynchronizationContext at the time of construction, the callbacks will be invoked on the ThreadPool.
By using Progress<T>.Report you're effectively queueing 20 tasks on the thread pool. There's no guarantee as to what order they're executed in.
There is a console application that simulates router functionality (packet swithcing and so on). I made a simple Windows Form that should show how much each router's socket is used. Each socket has different capacity and each Form "connected" to socket should show how much capacity there is still available.
My code so far:
static void Main(string[] args)
{
//get number of router's sockets
args = Environment.GetCommandLineArgs();
int socketnumber = Convert.ToInt32(args[2]);
//get sockets' capacity
int[] array = new int[socketnumber];
for (int i = 0; i < socketnumber; i++)
{
array[i] = Convert.ToInt32(args[3 + i]);
}
Now, LRM is a WinForm that shows each socket's (or, more accurately, link's attached to socket) status, so I initialize it and give it parameters.
LRM[] lrm = new LRM[socketnumber];
for (int i = 0; i < socketnumber; i++)
{
lrm[i] = new LRM();
lrm[i].Show();
a++;
}
for (int i = 0; i < socketnumber; i++)
{
Console.WriteLine(array[i]);
lrm[i].capacity = array[i];
lrm[i].available = array[i];
lrm[i].WriteCapacity(lrm[i].capacity);
lrm[i].WriteAvailable(lrm[i].available);
}
WriteCapacity and WriteAvailable are methods that are invoked by router to update values on LRM, like that:
public void WriteAvailable(int ava)
{
MethodInvoker mi = delegate ()
{
textBox2.Text = ava.ToString();
};
Invoke(mi);
}
Now, current problems I have:
1) Running multiple windows forms from console AND maintaining their functionality (all of them simultaneously), when number of windows forms varies (is set by command line argument)
2) Updating LRM values. When using show() method it just displays the form, it does not give it any values, and soon after form stops to respond, giving windows error. When using Application.Run() method, one form runs nicely, but neither other LRMs nor router's console works.
I appreciate Alexander Petrov's answer, but I found a way to solve my problem.
I tried Thread approach. First I made most of my variables static:
static int[] array;
static LRM[] lrm;
static int port;
then I made method that will be acting as thread starting method
private static void startLRM(int i)
{
Console.WriteLine(i);
lrm[i].Text = "LRM R" + ((port / 10) - 120).ToString() + " S" + a.ToString();
a++;
Console.WriteLine(array[i]);
lrm[i].capacity = array[i];
lrm[i].available = array[i];
lrm[i].WriteCapacity(lrm[i].capacity);
lrm[i].WriteAvailable(lrm[i].available);
lrm[i].ShowDialog();
}
Then, in Main() method, I allocated memory for link resource managers,and in for loop I made as many LRMs as were needed.
lrm = new LRM[socketnumber];
for (int i = 0; i < socketnumber; i++)
{
lrm[i] = new LRM();
Thread thread = new Thread(() => startLRM(i));
thread.Start();
Thread.Sleep(150);
}
Sleeping was actually necessary, because for unknown reasons I got errors when it was not there.
Finally, I get what I needed - a console application, which shows what is happening, and few windows forms that shows in nice manner some values.
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.
I am brand new to the idea of BackgroundWorkers, so this has me a little perplexed.
So I created a new WPF Application and created a BackgroundWorker and List class variable:
public partial class MainWindow : Window
{
private BackgroundWorker bw = new BackgroundWorker();
private List<int> tempList = new List<int>();
...
Then I use the BackgroundWorker to populate that list: (In the same class btw)
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
Random r = new Random();
for (int j = 1; j <= 100; j++)
{
for (int i = 0; i < 1000; i++)
{
tempList.Add(r.Next(100));
}
...
}
}
Now here is the part that's getting me...
The code that populates that list seems to be working fine. When I step through its execution, *it behaves as I have intended until the exact moment the code exits the bw_DoWork method.* After that point, it reverts back to an empty list. I changed the list to static at one point but nothing changed.
So why is this List not persisting throughout the programs execution?
I am(was) almost certain that this is some issue with the list being allocated in different memory regions for each thread, but I simply know far too little about about BackgroundWorker and MultiThreading in general to diagnose it myself.
Any help would be appreciated.
Before you start using more expensive options such as locking or thread safe collections. Try out Threading Tasks. If they work then you have some kind of a problem with your BackgroundWorker, if they don't then your code touches the list somewhere and you'll have to trace that.. (I just think Tasks are so much easier to work with)
private void bw_DoWork()
{
Task.Factory.StartNew(
() =>
{
var r = new Random();
for (int j = 1; j <= 100; j++)
{
for (int i = 0; i < 1000; i++)
{
tempList.Add(r.Next(100));
}
//the rest of whaterver you're doing...
}
});
}
#Stephen Marsh like #Douglas said you need to wait until work is finish.
See this:
// this execute the DoWork asynchronously.
bw.RunWorkerAsync();
// asynchronously means the next line may be executed
// before the DoWork fill the list. In fact can be executed
// before the DoWork begin.
MessageBox.Show("Without wait: " + tempList.Count.ToString());
To correct you can add this line before call RunWorkerAsync:
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
and put this in any place of the MainWindows class.
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Completed: " + tempList.Count.ToString());
}
In my tests always the result was:
"Without wait: 0"
"Completed: 100000"