C# Count Threading Not Working [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Good afternoon everybody.
I am new to Parallel.ForEach and even newer to threading and I wanted to ask your opinion on what is wrong with this code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MultiThreading_Example
{
class theMeter {
int count1 = 0;
public void CounterMeter()
{
while (this.count1 < 10000)
{
this.count1++;
Console.WriteLine(this.count1);
}
}
}
class Program
{
static void Main(string[] args)
{
theMeter met = new theMeter();
ThreadStart countForMe = new ThreadStart(met.CounterMeter);
for (int i = 0; i < 1000; i++)
{
Thread t1 = new Thread(countForMe);
t1.Start();
t1.Join();
t1.Abort();
}
Console.ReadLine();
}
}
}
Any idea what is wrong with this? I mean, I have tried doing it without t1.Join() and also have tried doing it on one thread. All are at the same speed. How can I get he program to process faster?
Thanks in advance!

Here is sample of working example. The difference is that each thread is stored in list and started in parallel, and then in the end we wait for each thread.
class theMeter
{
private int count1 = 0;
public void CounterMeter()
{
while (this.count1 < 10000)
{
this.count1++;
Console.WriteLine(this.count1);
}
}
}
class Program
{
static void Main(string[] args)
{
theMeter met = new theMeter();
ThreadStart countForMe = new ThreadStart(met.CounterMeter);
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t1 = new Thread(countForMe);
t1.Start();
threads.Add(t1);
}
// here we will wait for completion of every thread that was created and added to list
threads.ForEach(t => t.Join());
Console.ReadLine();
}
}
This code has a couple of issues worth to mention:
Each thread uses the same theMeter instance, so each of them will iterate the same this.count1 variable, so it's not so thread safe. IMO, the better approach is to create own instance for each thread and divide work for each of them. So they won't share the same resources and it won't cause shared resource access issues.
If any of threads will stuck, then your program will freeze. As Join will wait unlimited amount of time for that. If your thread might take a lot of time(network, db, etc), then you can use Join with timeout and then call Abort. But still using of Abort method isn't recommended, as thread should complete his logic in graceful way, not by cruel interruption of Abort method.
In your orignal example you have 1000 threads, and it's too much, as they will fight for CPU resources and might make things much slower. But it will depend on actual things they will do and where bottleneck will be. If this is CPU intensive task, then thread count should be similar to CPUs count. If this they are doing network requests, then it might depend on network bandiwth.
Another way might be using real Parallel.ForEach or Task classes, that can make things a bit easier.
Sample with actual Parallel.ForEach will be like:
class Program
{
static void Main(string[] args)
{
theMeter met = new theMeter();
Enumerable.Range(0, 1000).AsParallel().ForAll((i) => met.CounterMeter());
Console.ReadLine();
}
}
But you won't have so much flexibility here, but it's easier

Related

Why does my thread id changes after reading asynchronously from a stream? [duplicate]

This question already has an answer here:
Thread control flow in async .NET Console program [duplicate]
(1 answer)
Closed 27 days ago.
I have this couple of methods:
private static bool loaded = false;
private static bool replaying = false;
private static string wIndex = String.Empty;
private static WorldData wData;
private static ConcurrentDictionary<int, List<long>> streamPosition
= new ConcurrentDictionary<int, List<long>>();
private static ConcurrentDictionary<int, List<string>> collectionNames
= new ConcurrentDictionary<int, List<string>>();
private static async void StartReplay()
{
try
{
Stopwatch st = new Stopwatch();
while (loaded)
{
while (replaying)
{
st.Start();
for (int i = 0; i < collectionNames.Count; i++)
{
XLogger.Log(toConsole.Debug, Thread.CurrentThread.ManagedThreadId
.ToString());
wData.CopyCollection(await DeserializeListFromStreamAsync(
wData.GetCollectionByName(collectionNames[Thread.CurrentThread
.ManagedThreadId][i]), i, new CancellationToken()));
}
st.Stop();
int sleepTime = DebriefingManager.replayRate
- (int)st.ElapsedMilliseconds;
if (sleepTime > 0)
{
Thread.Sleep(sleepTime);
}
else
{
XLogger.Log(toConsole.Bad, "Debriefing is slow, video may lag.");
XLogger.Log(toFile.System, "Debriefing is slow, video may lag.");
}
st.Reset();
}
}
}
catch (Exception e)
{
XLogger.Log(toConsole.Bad, e.ToString());
XLogger.Log(toFile.Error, e.ToString());
}
}
private static async Task<ConcurrentDictionary<string, T>>
DeserializeListFromStreamAsync<T>(
ConcurrentDictionary<string, T> coll, int i, CancellationToken cancellationToken)
{
var dataStructures = new ConcurrentDictionary<string, T>();
using (FileStream stream = File.OpenRead(DebriefingManager
.GetReadingStreamByCollection(coll)))
{
stream.Position = streamPosition[Thread.CurrentThread.ManagedThreadId][i];
using (var streamReader = new MessagePackStreamReader(stream))
{
XLogger.Log(toConsole.Debug,
$"{Thread.CurrentThread.ManagedThreadId} --- test 1");
ReadOnlySequence<byte>? msgpack = await streamReader
.ReadAsync(cancellationToken);
XLogger.Log(toConsole.Debug,
$"{Thread.CurrentThread.ManagedThreadId} --- test 2");
if (msgpack is null) return null;
dataStructures = MessagePackSerializer
.Deserialize<ConcurrentDictionary<string, T>>(
(ReadOnlySequence<byte>)msgpack, cancellationToken: cancellationToken);
}
streamPosition[Thread.CurrentThread.ManagedThreadId][i] = stream.Position;
}
return dataStructures;
}
StartReplay is run by three different threads.
I need to have a unique id for each thread as I need the List<long> and List<string> to be unique for each one. So I thought about using ConcurrentDictionaries and the Thread.CurrentThread.ManagedThreadId as a key.
The first thing I tried was to use Thread.CurrentThread.ManagedThreadId but I discovered that after this line: ReadOnlySequence<byte>? msgpack = await streamReader.ReadAsync(cancellationToken); the Id changed. Not knowing that it should be immutable I thought nothing of it and tried to use the [ThreadStatic] attribute, but after that same line the value of the variable tagged was reset to 0.
After using the Thread debug window I found out that the threads that ran my code were "killed" after that line and new ones were used to continue the code.
My question than is: why does this happen? And how do I prevent it? Might this be impacting performance?
EDIT: I should also add that the method is a modified version of the one in the MessagePack documentation in the "Multiple MessagePack structures on a single Stream
" section.
Why does this happen?
Because this is the nature of the beast (asynchrony). The completion of asynchronous operations happens on a thread that is usually different than the thread that initiated the asynchronous operation. This is especially true for Console applications, that are not equipped with any specialized mechanism that restores the original thread after the await. It would be different if you had, for example, a Windows Forms app. These applications start by installing a specialized scheduler on the UI thread, called WindowsFormsSynchronizationContext, which intervenes after the await, and schedules the continuation back on the UI thread. You don't have such a thing in a Console application, so you are experiencing the effects of asynchrony in its purest form.
How do I prevent it?
By not having asynchronous execution flows. Just wait synchronously all the asynchronous operations, and you'll be in the same thread from start to finish:
ReadOnlySequence<byte>? msgpack = streamReader
.ReadAsync(cancellationToken).GetAwaiter().GetResult();
If you find it tiresome to write .GetAwaiter().GetResult() everywhere, you can shorten it to .Wait2() with these two extension methods:
public static void Wait2(this Task task) => task.GetAwaiter().GetResult();
public static TResult Wait2<TResult>(this Task<TResult> task) => task.GetAwaiter().GetResult();
Might this be impacting performance?
It might impact the memory efficiency. Your threads will be blocked during the asynchronous operations, so you program might need more threads than usual. This could have some temporary effects on performance, in case the ThreadPool becomes saturated, and needs to spawn more threads. The thread-injecting heuristics are a bit conservative, by injecting at maximum one new thread per second. In case this is a problem, you can configure the ThreadPool in advance with the ThreadPool.SetMinThreads method.
Note: Blocking the current thread with .GetAwaiter().GetResult() is not a good way to write code in general. It violates the common wisdom of not blocking on async code. Here I am just answering directly your question about how to prevent the thread from changing. I am not advising you to actually do it. If you asked for my advice, I would say to rethink everything that you have done so far, and maybe restart your project from scratch.

Μeasuring the time of a thread quantum [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I'm trying to measure the time each thread quantum takes using c#.
using System;
using System.Diagnostics;
using System.Threading;
using System.Collections.Concurrent;
namespace pr
{
public static class Program
{
private static Stopwatch watch = new Stopwatch();
private static long t = 0;
private static volatile int id = 0;
private static BlockingCollection<long> deltas = new();
public static void Main(string[] args)
{
ProcessAffinity();
PriorityClass();
ThreadDemo();
}
private static void ProcessAffinity()
{
Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)(1 << 0);
}
private static void PriorityClass()
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
}
private static void ThreadDemo()
{
var thread1 = new Thread(() => InsideThread())
{
IsBackground = true,
Priority = ThreadPriority.Highest
};
var thread2 = new Thread(() => InsideThread())
{
IsBackground = true,
Priority = ThreadPriority.Highest
};
watch.Start();
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
var avg = deltas.Average();
Console.WriteLine("Average: " + avg);
foreach (var e in deltas)
{
Console.WriteLine("delta: " + e);
}
}
private static void InsideThread()
{
while (true)
{
var currentId = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("id" + currentId);
if (id == 0)
{
id = currentId;
}
if (id != currentId)
{
var newt = watch.ElapsedMilliseconds;
deltas.Add(newt - t);
t = newt;
id = currentId;
}
if (watch.ElapsedMilliseconds > 3000) break;
}
}
}
}
If I print the id of the current thread to the console, everything kind of works and the delta gets counted. But the Console.WriteLine changes the context (I guess? I'm new in this topic) and increases the time, so the result is not correct (it's around 100 ms, while it's supposed to be around 32 ms). However, if I comment the Console.WriteLine("id" + currentId); out, the threads don't change: thread2 seems to start only after thread1 completes its work, so the final delta is 3000ms + something. Increasing the time doesn't help too. My question is: why don't the threads run simultaneously when Console.WriteLine() is commented out? How to measure the time of a thread quantum correctly? Should I use any locks? (I've tried, but nothing changed)
My guess is that Console.WriteLine will yield the time slice, possibly due to blocking on a lock. This is not really unexpected.
Without yielding, the thread1 will have a higher priority than your "main" thread. So it is likely that thread2.Start(); will never be run before the thread1 has completed.
To get around this you could use a manualResetEvent. Let each thread wait on the same event, and set this from the main thread after both have been started. Waiting on the event will block the threads, letting the main thread run. When the event has been set, both threads should be eligible to run.
Note that I'm not at all sure that this will give any accurate results, but it should fix the current behavior you are seeing.

Can this code work as asynchronous? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I want to run GetAnswerToLife method to wait for 5 seconds and then print 210 while "for loop" is printing the numbers. But below code only prints the for loop and I can not make this async method work. 210 is not seen anywhere. Is there anything I am missing here?
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication30
{
internal class Program
{
private static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
int answer = 21 * 10;
return answer;
}
private static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
int a = GetAnswerToLife().Result;
Console.WriteLine(a);
}
}
}
It works but they are not working asynchronously. After for loop
finishes printing, after that 210 is printed. What I want it for loop
and other method starts at the same time.
I think you are confusing asynchronous work with parallelism. Asynchronous is doing work , but not blocking the thread , once your thread hit await it actually is released to the thread pool to do some other job, while waiting for the statement after await to evaluate, only after this the execution continues.
Parallelism is where work is done in parallel, hence the name of the action.
Consider this as an example.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
Parallel.Invoke(PrintLoop, async () => Console.WriteLine(await GetAnswerToLife()));
}
public static void PrintLoop()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
public static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
return 21 * 10;
}
}
}
Now 210 will be printed somewhere between numbers 1 and 100, which is different and I think this was what you wanted initially.
#Stephen Cleary explanations about async operations are really off the chart, you should definitely check as a further readings.
You are calling the GetAnswerToLife after the loop. Obviously, it will be executed after the loop.
If you want the answer to life computed in the same time as your loop, call it before the start of the loop:
private static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
int answer = 21 * 10;
Console.WriteLine(answer);
return answer;
}
private static void Main(string[] args)
{
var answering = GetAnswerToLife();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
// Calling .Result will ensure the answer has been calculated
int a = answering.Result;
}
I also changed your answer to life implementation so it prints the answer in console in order to know the answer when it is done calculating and not at the end of the loop.

How to run 2 functions simultaneously? [duplicate]

This question already has answers here:
How can I run both of these methods 'at the same time' in .NET 4.5?
(5 answers)
Closed 6 years ago.
I know this question had been answered a thousand times, but i still can't get the functions to work at the same time. Here is my code:
static void Main(string[] args)
{
a();
a();
}
static void a()
{
string sampleString = "a";
Console.WriteLine(sampleString);
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.1));
Console.SetCursorPosition(0, Console.CursorTop -1);
sampleString = " " + sampleString;
Console.WriteLine(sampleString);
}
}
The function just writes the letter 'a' and after 0.1 seconds adds a space behind it, not complicated. After the function ends, it does the same thing again. I want both of the functions to work at the same time, the first function in the first line and the second in the second line.
Thanks in advance.
You can use Parallel class:
static void Main(string[] args)
{
Parallel.Invoke(a,a);
}
You functions will be run simultaneously.
An easy solution would be to create two threads, start them and wait for them to finish. For your specific question:
static void Main(string[] args)
{
var t1 = new Thread(a); t1.Start();
var t2 = new Thread(a); t2.Start();
t1.Join(); t2.Join();
}
But of course, this does not solve your initial problem, writing into different lines of the console, as the a function does not know, which line to write on. You could solve this, by adding a parameter with the line number.
Furthermore, you'll have to protect your console output by a lock, because it's a single target where multiple sources write data into, which may lead to inconsistencies if not synchronized correctly. So I really suggest, that you read some tutorials on multi-threading.

Unordered threads problem

I had asked question about lock in here and people responded there is no problem in my lock implementation. But i catched problem. Here is same lock implementation and i am getting weird result. I expect to see numbers starts from 1 but it starts from 5.Example is at below.
class Program
{
static object locker = new object();
static void Main(string[] args)
{
for (int j = 0; j < 100; j++)
{
(new Thread(new ParameterizedThreadStart(dostuff))).Start(j);
}
Console.ReadKey();
}
static void dostuff(dynamic input)
{
lock (locker)
{
Console.WriteLine(input);
}
}
}
The code is fine. But you cannot guarantee the order the threads are executed in. When I run the code I get:
0
1
3
5
2
4
6
10
9
11
7
12
8
etc
If you need to run the threads in a specified order, you could look into using ThreadPool.QueueUserWorkItem instead.
class Program
{
static object locker = new object();
static EventWaitHandle clearCount
=new EventWaitHandle(false, EventResetMode.ManualReset);
static void Main(string[] args)
{
for (int j = 0; j < 100; j++)
{
ThreadPool.QueueUserWorkItem(dostuff, j);
}
clearCount.WaitOne();
}
static void dostuff(dynamic input)
{
lock (locker)
{
Console.WriteLine(input);
if (input == 99) clearCount.Set();
}
}
}
It doesn't make sense to put a lock where you're putting it, as you're not locking code which changes a value shared by multiple threads. The section of code you're locking doesn't change any variables at all.
The reason the numbers are out of order is because the threads aren't guaranteed to start in any particular order, unless you do something like #Mikael Svenson suggests.
For an example of a shared variable, if you use this code:
class Program
{
static object locker = new object();
static int count=0;
static void Main(string[] args)
{
for (int j = 0; j < 100; j++)
{
(new Thread(new ParameterizedThreadStart(dostuff))).Start(j);
}
Console.ReadKey();
}
static void dostuff(object Id)
{
lock (locker)
{
count++;
Console.WriteLine("Thread {0}: Count is {1}", Id, count);
}
}
}
You'll probably see that the Thread numbers aren't in order, but the count is. If you remove the lock statement, the count won't be in order either.
You have a couple of problems and wrong assumptions here.
Creating 100 threads in this fashion is not recommended.
The threads are not going to execute in the order they are started.
Placing the lock where you have it will effectively serialize the execution of the threads immediately removing any advantage you were hoping to gain by using threading.
The best approach to use is to partition your problem into separate independent chunks which can be computed simultaneously using only the least amount of thread synchronization as possible. These partitions should be executed on small and fairly static number of threads. You can use the ThreadPool, Parallel, or Task classes for doing this.
I have included a sample pattern using the Parallel.For method. To make the sample easy to understand lets say you have a list of objects that you want to clone and land into a separate list. Lets assume the clone operation is expensive and that you want to parallelize the cloning of many objects. Here is how you would do it. Notice the placement and limited use of the lock keyword.
public static void Main()
{
List<ICloneable> original = GetCloneableObjects();
List<ICloneable> copies = new List<ICloneable>();
Parallel.For(0, 100,
i =>
{
ICloneable cloneable = original[i];
ICloneable copy = cloneable.Clone();
lock (copies)
{
copies.Add(copy);
}
});
}

Categories

Resources