I am inside a threat updating a graph and I go into a routine that makes a measurement for 4 seconds. The routine returns a double. What I am noticing is that my graph stops showing activity for 4 seconds until I am done collecting data. I need to start a new thread and put the GetTXPower() activity in the background. So in other words I want GetTXPower() and the graph charting to run in parallel. Any suggestions?
here is my code:
stopwatch.Start();
// Get Tx Power reading and save the Data
_specAn_y = GetTXPower();
_pa_Value = paData.Start;
DataPoint.Measurement = _specAn_y;
//Thread.Sleep(50);
double remaining = 0;
do
{
charting.stuff
}
uxChart.Update();
I suggest looking into Task Parallel Library.
Starting with the .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code.
Since you also need the result back from GetTXPower, I would use a Task<double> for it.
Task<double> task = Task.Factory.StartNew<double>(GetTXPower);
Depending on when you need the result, you can query if the task has completed by checking task.IsCompleted or alternatively block the thread and wait for the task to finish by calling task.Wait(). You can fetch the result through task.Result property.
An alternative would be to add a continuation to the initial task:
Task.Factory.StartNew<double>(GetTXPower).ContinueWith(task =>
{
// Do something with the task result.
});
Make a void method (I'll call it MeasureMentMethod) that collects the data. The create a Thread using the following code:
Thread MeasurementThread = new Thread(new ThreadStart(MeasurementMethod));
You can then run the thread with
MeasurementThread.Start();
And if your Thread has something like this:
while(true){
//Run your code here
Thread.Sleep(100);
}
Then you can just start it at the beginning, and it will just keep collecting data.
So, you would have your main thread that would update the chart, and you would start the thread that would get the data on the side.
Related
I have this code:
var dt = new DeveloperTest();
var tasks = readers.Select(dt.ProcessReaderAsync).ToList();
var printCounterTask = new Task(() => dt.DelayedPrint(output));
printCounterTask.Start();
Task.WhenAll(tasks).ContinueWith(x => dt.Print(output).ContinueWith(_ =>
{
dt.Finished = true;
})).Wait();
printCounterTask.Wait();
What this does is preparing tasks that will be run and then start a (I think ) parallel execution which starts with:
printCounterTask.Start();
this is what delayed print does:
public async Task DelayedPrint(IOutputResult output)
{
while (true)
{
if (!Finished)
{
//every 10 seconds should print.
//at least one print even if the execution is less than 10 seconds
//as this starts in paralel with the processing
Task.Delay(10 * 1000).Wait();
await Print(output);
}
else
{
#if DEBUG
Console.WriteLine("Finished with printing");
#endif
break;
}
}
}
Basically is printing some output that is delayed every 10 seconds, then when all the tasks are complete stops the infinite loop.
if you want to see the whole code is here https://github.com/velchev/Exclaimer-Test
I am not sure if this
Task.WhenAll(tasks).ContinueWith(x => dt.Print(output).ContinueWith(_ =>
{
dt.Finished = true;
})).Wait();
runs in parallel with printCounterTask.Start();
When I debut it seems it does as a breakpoint in the !Finished code is hit and then in the else clause too. As far as I know when you start a task it runs in parallel so all the tasks should run in parallel. A task is a representation of a thread which syntactically is easier to control compared to the old syntax. So all this threads running and because of the better syntax is easier to say - wait till all finish and then change the flag. Any helpful explanation will be appreciated. Thank you mates.
The code is mostly correct as written, but there are some nuances around the Task constructor and ContinueWith that make it difficult to understand, and make it easy to break. For example, printCounterTask.Wait() will not wait until DelayedPrint completes, because the Task constructor does not understand asynchronous delegates.
To make the code fully correct and much easier to read and reason about, replace new Task/Start with Task.Run, and replace ContinueWith with await:
var dt = new DeveloperTest();
var tasks = readers.Select(dt.ProcessReaderAsync).ToList();
var printCounterTask = Task.Run(() => dt.DelayedPrint(output));
await Task.WhenAll(tasks);
await dt.Print(output);
dt.Finished = true;
await printCounterTask;
You will also find your code to be clearer if you follow the convention of suffixing asynchronous methods with Async.
A task is a representation of a thread which syntactically is easier to control compared to the old syntax.
No, not at all. A task is a Future - a representation of an operation that may complete sometime in the future. This "operation" does not necessarily require a thread. Task.Run does queue work to the thread pool, but in this example, the task does not always use a thread pool thread (specifically, it doesn't use a thread pool thread during the await Task.Delay).
You are partly right.
The tasks will run in parallel with
printCounterTask
as expected.
However a task is not a representation of a thread and not a syntactic sugaring which easier to control over thread.
Here you can find a useful information:
https://www.dotnetforall.com/difference-task-and-thread/
In general it's important for you to understand that Tasks are using Threads from the ThreadPool.
A task is a representation of a method you wish to execute as a background work (you don't want to block the current execution), and a task needs a thread in order to operate, but it's not true that a task is a thread.
You may have more tasks than available threads in the thread pool, which will lead to them waiting in the queue for available thread in order to be executed.
Also take in consideration that Task.WhenAll will not execute the tasks for you, you'll have to execute them yourself (implementation of ProcessReaderAsync is missing, but if you're using Task.Run it's OK).
If I am creating Tasks using a for loop will those tasks run in parallel or would they just run one after the other?
Here is my code -
private void initializeAllSpas()
{
Task[] taskArray = new Task[spaItems.Count];
for(int i = 0; i < spaItems.Count; i++)
{
taskArray[i] = Task.Factory.StartNew(() => spaItems[i].initializeThisSpa());
}
Task.WhenAll(taskArray).Wait();
foreach (var task in taskArray) task.Dispose();
}
where spaItems is a list of items from another class, call it SpaItem, in which the initializeThisSpa() function opens a file and updates the information for that particular SpaItem.
My question is, does the above code actually excute initializeThisSpa() on all of the spaItems at the same time? if not, how can I correct that?
(I Ignored syntax issues if any and not tested)
At the same time?..
Not guaranteed. At least (the best bet) definitely there will be nano secs difference.
Tasks are placed in a queue.
And every task waits for its opportunity for a thread from threadpool, for its turn of execution.
It all depends on the availability of threads in thread pool. If no thread available, the tasks waits in queue.
There are different states for the task before its final execution. Here is a good explanation. And after going through this link, you will come to know that it is almost impossible to call a function at the same time from multiple tasks.
https://blogs.msdn.microsoft.com/pfxteam/2009/08/30/the-meaning-of-taskstatus/
You can achieve tasks sequentially (one after another) calling a specific function by creating tasks with methods like "ContinueWith, ContinueWhenAll, ContinueWhenAny,"
An example is below in MSDN documentation link.
https://msdn.microsoft.com/en-us/library/dd321473(v=vs.110).aspx
I am new to threaded programming. I have to run few tasks in PARALLEL and in Background (so that main UI execution thread remain responsive to user actions) and wait for each one of them to complete before proceeding further execution.
Something like:
foreach(MyTask t in myTasks)
{
t.DoSomethinginBackground(); // There could be n number of task, to save
// processing time I wish to run each of them
// in parallel
}
// Wait till all tasks complete doing something parallel in background
Console.Write("All tasks Completed. Now we can do further processing");
I understand that there could be several ways to achieve this. But I am looking for the best solution to implement in .Net 4.0 (C#).
To me it would seem like you want Parallel.ForEach
Parallel.ForEach(myTasks, t => t.DoSomethingInBackground());
Console.Write("All tasks Completed. Now we can do further processing");
You can also perform multiple tasks within a single loop
List<string> results = new List<string>(myTasks.Count);
Parallel.ForEach(myTasks, t =>
{
string result = t.DoSomethingInBackground();
lock (results)
{ // lock the list to avoid race conditions
results.Add(result);
}
});
In order for the main UI thread to remain responsive, you will want to use a BackgroundWorker and subscribe to its DoWork and RunWorkerCompleted events and then call
worker.RunWorkerAsync();
worker.RunWorkerAsync(argument); // argument is an object
You can use Task library to complete:
string[] urls = ...;
var tasks = urls.Select(url => Task.Factory.StartNew(() => DoSomething(url)));
To avoid locking UI Thread, you can use ContinueWhenAll in .NET 4.0:
Task.Factory.ContinueWhenAll(tasks.ToArray(), _ =>
Console.Write("All tasks Completed. Now we can do further processing");
);
If you are in the latest version of .NET, you can use Task.WhenAll instead
If you use Net 4.0 or up, refer to the Parallel class and Task class. Joseph Albahari wrote very clear book about that: http://www.albahari.com/threading/part5.aspx#_Creating_and_Starting_Tasks
I need somehow to bypass Thread.Sleep() method and don't get my UI Thread blocked, but I don't have to delete the method.
I need to solve the problem without deleting the Sleep method. The Sleep method simulates a delay(unresponsive application). I need to handle that.
An application is considered non-responsive when it doesn't pump its message queue. The message queue in Winforms is pumped on the GUI thread. Therefore, to make your application "responsive", you need to make sure the GUI thread has opportunities to pump the message queue - in other words, it must not run your code.
You mentioned that the Thread.Sleep simulates a "delay" in some operation you're making. However, you need to consider two main causes of such "delays":
An I/O request waiting for completion (reading a file, querying a database, sending an HTTP request...)
CPU work
The two have different solutions. If you're dealing with I/O, the best way would usually be to switch over to using asynchronous I/O. This is a breeze with await:
var response = await new HttpClient().GetAsync("http://www.google.com/");
This ensures that your GUI thread can do its job while your request is pending, and your code will restore back on the UI thread after the response gets back.
The second one is mainly solved with multi-threading. You should be extra careful when using multi-threading, because it adds in many complexities you don't get in a single-threaded model. The simplest way of treating multi-threading properly is by ensuring that you're not accessing any shared state - that's where synchronization becomes necessary. Again, with await, this is a breeze:
var someData = "Very important data";
var result = await Task.Run(() => RunComplexComputation(someData));
Again, the computation will run outside of your UI thread, but as soon as its completed and the GUI thread is idle again, your code execution will resume back on the UI thread, with the proper result.
something like that maybe ?
public async void Sleep(int milliseconds)
{
// your code
await Task.Delay(milliseconds); // non-blocking sleep
// your code
}
And if, for reasons that escape me, you HAVE to use Thread.Sleep, you can handle it like that :
public async void YourMethod()
{
// your code
await Task.Run(() => Thread.Sleep(1000)); // non-blocking sleep using Thread.Sleep
// your code
}
Use MultiThreading.
Use a different thread for sleep rather than the main GUI thread. This way it will not interfere with your Main application
I have a function where I want to execute in a separate thread avoiding two threads to access the same resources. Also I want to make sure that if the thread is currently executing then stop that thread and start executing the new thread. This is what I have:
volatile int threadCount = 0; // use it to know the number of threads being executed
private void DoWork(string text, Action OncallbackDone)
{
threadCount++;
var t = new Thread(new ThreadStart(() =>
{
lock (_lock) // make sure that this code is only accessed by one thread
{
if (threadCount > 1) // if a new thread got in here return and let the last one execute
{
threadCount--;
return;
}
// do some work in here
Thread.Sleep(1000);
OncallbackDone();
threadCount--;
}
}));
t.Start();
}
if I fire that method 5 times then all the threads will be waiting for the lock until the lock is released. I want to make sure that I execute the last thread though. when the threads are waiting to be the owner of the lock how can I determine which will be the next one owning the lock. I want them to own the resource in the order that I created the threads...
EDIT
I am not creating this application with .net 4.0 . Sorry for not mentioning what I was trying to accomplish. I am creating an autocomplete control where I am filtering a lot of data. I don't want the main window to freeze eveytime I want to filter results. also I want to filter results as the user types. If the user types 5 letters at once I want to stop all threads and I will just be interested in the last one. because the lock blocks all the threads sometimes the last thread that I created may own the lock first.
I think you are overcomplicating this. If you are able to use 4.0, then just use the Task Parallel Library. With it, you can just set up a ContinueWith function so that threads that must happen in a certain order are done in the order you dictate. If this is NOT what you are looking for, then I actually would suggest that you not use threading, as this sounds like a synchronous action that you are trying to force into parallelism.
If you are just looking to cancel tasks: then here is a SO question on how to cancel TPL tasks. Why waste the resources if you are just going to dump them all except for the last one.
If you are not using 4.0, then you can accomplish the same thing with a Background Worker. It just takes more boilerplate code to accomplish the same thing :)
I agree with Justin in that you should use the .NET 4 Task Parallel Library. But if you want complete control you should not use the default Task Scheduler, which favors LIFO, but create your own Task Scheduler (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx) and implement the logic that you want to determine which task gets preference.
Using Threads directly is not recommended unless you have deep knowledge of .NET Threading. If you are on .NET 4.0; Tasks and TPL are preferred.
This is what I came up with after reading the links that you guys posted. I guess I needed a Queue therefore I implemented:
volatile int threadCount = 0;
private void GetPredicateAsync(string text, Action<object> DoneCallback)
{
threadCount++;
ThreadPool.QueueUserWorkItem((x) =>
{
lock (_lock)
{
if (threadCount > 1) // disable executing threads at same time
{
threadCount--;
return; // if a new thread is created exit.
// let the newer task do work!
}
// do work in here
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
threadCount--;
DoneCallback(Foo);
}));
}
},text);
}