loop and thread are working parallel - c#

my case is:
loop and thread are working parallel.. i want to stop the execution of loop untill thread is done with its functionality, when the thread state is stopped, at that time i want to execute the loop further..
for (int pp = 0; pp < LstIop.Count; pp++)
{
oCntrlImageDisplay = new CntrlImageDisplay();
oCntrlImageEdit = new CntrlImageEdit();
axAcroPDF1 = new AxAcroPDFLib.AxAcroPDF();
int pages = ConvertFileIntoBinary(LstIop[pp].Input, oCntrlImageEdit);
oCntrlImageDisplay.ImgDisplay.Image = LstIop[pp].Output;
oCntrlImageDisplay.ImgEditor.Image = oCntrlImageDisplay.ImgDisplay.Image;
if (t1 == null || t1.ThreadState.ToString() == "Stopped")
{
t1 = new Thread(() => convert(pages, LstIop[pp].Input, LstIop[pp].Output, stIop[pp].Temp));
t1.SetApartmentState(ApartmentState.STA);
t1.IsBackground = true;
CheckForIllegalCrossThreadCalls = false;
t1.Start();
}
}

as the others have said, there is no point in threading here, but if your hell bent on it, do Async. just use .Invoke or, .begininvoke followed by a .endInvoke
EX:
delegate void T2();
static void Main(string[] args)
{
T2 Thread = new T2(Work);
while (true)
{
IAsyncResult result = Thread.BeginInvoke(null, null);
//OTHER WORK TO DO
Thread.EndInvoke(result);
}
}
static void Work()
{
//WORK TO DO
}
using delegates is nice because you can specify return data, and send parameters
delegate double T2(byte[] array,string text, int num);
static void Main(string[] args)
{
T2 Thread = new T2(Work);
while (true)
{
IAsyncResult result = Thread.BeginInvoke(null, null);
//OTHER WORK TO DO
double Returned = Thread.EndInvoke(result);
}
}
static double Work(byte[] array, string text, int num)
{
// WORK TO DO
return(3.4);
}

To wait for the thread to finish executing, call:
t1.join();

Related

How to return result from delegate that performing in thread? [duplicate]

How do I return a value from a thread?
One of the easiest ways to get a return value from a thread is to use closures. Create a variable that will hold the return value from the thread and then capture it in a lambda expression. Assign the "return" value to this variable from the worker thread and then once that thread ends you can use it from the parent thread.
void Main()
{
object value = null; // Used to store the return value
var thread = new Thread(
() =>
{
value = "Hello World"; // Publish the return value
});
thread.Start();
thread.Join();
Console.WriteLine(value); // Use the return value here
}
It depends on how do you want to create the thread and available .NET version:
.NET 2.0+:
A) You can create the Thread object directly. In this case you could use "closure" - declare variable and capture it using lambda-expression:
object result = null;
Thread thread = new System.Threading.Thread(() => {
//Some work...
result = 42; });
thread.Start();
thread.Join();
Console.WriteLine(result);
B) You can use delegates and IAsyncResult and return value from EndInvoke() method:
delegate object MyFunc();
...
MyFunc x = new MyFunc(() => {
//Some work...
return 42; });
IAsyncResult asyncResult = x.BeginInvoke(null, null);
object result = x.EndInvoke(asyncResult);
C) You can use BackgroundWorker class. In this case you could use captured variable (like with Thread object) or handle RunWorkerCompleted event:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) => {
//Some work...
e.Result = 42;
};
worker.RunWorkerCompleted += (s, e) => {
//e.Result "returned" from thread
Console.WriteLine(e.Result);
};
worker.RunWorkerAsync();
.NET 4.0+:
Starting with .NET 4.0 you could use Task Parallel Library and Task class to start your threads. Generic class Task<TResult> allows you to get return value from Result property:
//Main thread will be blocked until task thread finishes
//(because of obtaining the value of the Result property)
int result = Task.Factory.StartNew(() => {
//Some work...
return 42;}).Result;
.NET 4.5+:
Starting with .NET 4.5 you could also use async/await keywords to return value from task directly instead of obtaining Result property:
int result = await Task.Run(() => {
//Some work...
return 42; });
Note: method, which contains the code above shoud be marked with asynckeyword.
For many reasons using of Task Parallel Library is preferable way of working with threads.
I would use the BackgroundWorker approach and return the result in e.Result.
EDIT:
This is commonly associated with WinForms and WPF, but can be used by any type of .NET application. Here's sample code for a console app that uses BackgroundWorker:
using System;
using System.Threading;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
namespace BGWorker
{
class Program
{
static bool done = false;
static void Main(string[] args)
{
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
bg.RunWorkerAsync();
while (!done)
{
Console.WriteLine("Waiting in Main, tid " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
}
}
static void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("Completed, tid " + Thread.CurrentThread.ManagedThreadId);
done = true;
}
static void bg_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Work Line: " + i + ", tid " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(500);
}
}
}
}
Output:
Waiting in Main, tid 10
Work Line: 1, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 2, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 3, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 4, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 5, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Completed, tid 6
2014 UPDATE
See #Roger's answer below.
https://stackoverflow.com/a/24916747/141172
He points out that you can use a Task that returns a Task<T>, and check Task<T>.Result.
A thread isn't a method - you don't normally "return" a value.
However, if you're trying to fetch a value back from the results of some processing, you have many options, the two main ones being:
You can synchronize a shared piece of data, and set it appropriately.
You can also pass the data back in some form of callback.
It really depends on how you're creating the thread, and how you want to use it, as well as the language/framework/tools you're using.
Simply use the delegate approach.
int val;
Thread thread = new Thread(() => { val = Multiply(1, 2); });
thread.Start();
Now make Multiply function that will work on another thread:
int Multiply(int x, int y)
{
return x * y;
}
My favorite class, runs any method on another thread with just 2 lines of code.
class ThreadedExecuter<T> where T : class
{
public delegate void CallBackDelegate(T returnValue);
public delegate T MethodDelegate();
private CallBackDelegate callback;
private MethodDelegate method;
private Thread t;
public ThreadedExecuter(MethodDelegate method, CallBackDelegate callback)
{
this.method = method;
this.callback = callback;
t = new Thread(this.Process);
}
public void Start()
{
t.Start();
}
public void Abort()
{
t.Abort();
callback(null); //can be left out depending on your needs
}
private void Process()
{
T stuffReturned = method();
callback(stuffReturned);
}
}
usage
void startthework()
{
ThreadedExecuter<string> executer = new ThreadedExecuter<string>(someLongFunction, longFunctionComplete);
executer.Start();
}
string someLongFunction()
{
while(!workComplete)
WorkWork();
return resultOfWork;
}
void longFunctionComplete(string s)
{
PrintWorkComplete(s);
}
Beware that longFunctionComplete will NOT execute on the same thread as starthework.
For methods that take parameters you can always use closures, or expand the class.
Here is a simple example using a delegate ...
void Main()
{
DoIt d1 = Doer.DoThatThang;
DoIt d2 = Doer.DoThatThang;
IAsyncResult r1 = d1.BeginInvoke( 5, null, null );
IAsyncResult r2 = d2.BeginInvoke( 10, null, null );
Thread.Sleep( 1000 );
var s1 = d1.EndInvoke( r1 );
var s2 = d2.EndInvoke( r2 );
s1.Dump(); // You told me 5
s2.Dump(); // You told me 10
}
public delegate string DoIt( int x );
public class Doer
{
public static string DoThatThang( int x )
{
return "You told me " + x.ToString();
}
}
There's a terrific series on threading at Threading in C#.
With the latest .NET Framework, it is possible to return a value from a separate thread using a Task, where the Result property blocks the calling thread until the task finishes:
Task<MyClass> task = Task<MyClass>.Factory.StartNew(() =>
{
string s = "my message";
double d = 3.14159;
return new MyClass { Name = s, Number = d };
});
MyClass test = task.Result;
For details, please see http://msdn.microsoft.com/en-us/library/dd537613(v=vs.110).aspx
ThreadStart delegates in C# used to start threads have return type 'void'.
If you wish to get a 'return value' from a thread, you should write to a shared location (in an appropriate thread-safe manner) and read from that when the thread has completed executing.
I came across this thread when also trying to obtain the return value of a method that gets executed within a Thread. I thought I would post my solution that works.
This solution uses an class to store both the method to be executed (indirectly) and stores the returning value. The class can be used for any function and any return type. You just instantiate the object using the return value type and then pass the function to call via a lambda (or delegate).
C# 3.0 Implementation
public class ThreadedMethod<T>
{
private T mResult;
public T Result
{
get { return mResult; }
private set { mResult = value; }
}
public ThreadedMethod()
{
}
//If supporting .net 3.5
public void ExecuteMethod(Func<T> func)
{
Result = func.Invoke();
}
//If supporting only 2.0 use this and
//comment out the other overload
public void ExecuteMethod(Delegate d)
{
Result = (T)d.DynamicInvoke();
}
}
To use this code you can use a Lambda (or a delegate). Here is the example using lambdas:
ThreadedMethod<bool> threadedMethod = new ThreadedMethod<bool>();
Thread workerThread = new Thread((unused) =>
threadedMethod.ExecuteMethod(() =>
SomeMethod()));
workerThread.Start();
workerThread.Join();
if (threadedMethod.Result == false)
{
//do something about it...
}
VB.NET 2008 Implementation
Anyone using VB.NET 2008 can't use lambdas with non-value returning methods. This affects the ThreadedMethod class, so we'll make ExecuteMethod return the value of the function. This doesn't hurt anything.
Public Class ThreadedMethod(Of T)
Private mResult As T
Public Property Result() As T
Get
Return mResult
End Get
Private Set(ByVal value As T)
mResult = value
End Set
End Property
Sub New()
End Sub
'If supporting .net 3.5'
Function ExecuteMethod(ByVal func As Func(Of T)) As T
Result = func.Invoke()
Return Result
End Function
'If supporting only 2.0 use this and'
'comment out the other overload'
Function ExecuteMethod(ByVal d As [Delegate]) As T
Result = DirectCast(d.DynamicInvoke(), T)
Return Result
End Function
End Class
If you don't want to use a BackgroundWorker, and just use a regular Thread, then you can fire an event to return data like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadWithDataReturnExample
{
public partial class Form1 : Form
{
private Thread thread1 = null;
public Form1()
{
InitializeComponent();
thread1 = new Thread(new ThreadStart(this.threadEntryPoint));
Thread1Completed += new AsyncCompletedEventHandler(thread1_Thread1Completed);
}
private void startButton_Click(object sender, EventArgs e)
{
thread1.Start();
//Alternatively, you could pass some object
//in such as Start(someObject);
//With apprioriate locking, or protocol where
//no other threads access the object until
//an event signals when the thread is complete,
//any other class with a reference to the object
//would be able to access that data.
//But instead, I'm going to use AsyncCompletedEventArgs
//in an event that signals completion
}
void thread1_Thread1Completed(object sender, AsyncCompletedEventArgs e)
{
if (this.InvokeRequired)
{//marshal the call if we are not on the GUI thread
BeginInvoke(new AsyncCompletedEventHandler(thread1_Thread1Completed),
new object[] { sender, e });
}
else
{
//display error if error occurred
//if no error occurred, process data
if (e.Error == null)
{//then success
MessageBox.Show("Worker thread completed successfully");
DataYouWantToReturn someData = e.UserState as DataYouWantToReturn;
MessageBox.Show("Your data my lord: " + someData.someProperty);
}
else//error
{
MessageBox.Show("The following error occurred:" + Environment.NewLine + e.Error.ToString());
}
}
}
#region I would actually move all of this into it's own class
private void threadEntryPoint()
{
//do a bunch of stuff
//when you are done:
//initialize object with data that you want to return
DataYouWantToReturn dataYouWantToReturn = new DataYouWantToReturn();
dataYouWantToReturn.someProperty = "more data";
//signal completion by firing an event
OnThread1Completed(new AsyncCompletedEventArgs(null, false, dataYouWantToReturn));
}
/// <summary>
/// Occurs when processing has finished or an error occurred.
/// </summary>
public event AsyncCompletedEventHandler Thread1Completed;
protected virtual void OnThread1Completed(AsyncCompletedEventArgs e)
{
//copy locally
AsyncCompletedEventHandler handler = Thread1Completed;
if (handler != null)
{
handler(this, e);
}
}
#endregion
}
}
Can use This Code:
private Object MyThread(Object Data)
{
Object response = null;
Thread newThread = new Thread(() =>
{
response = MyFunction(Data);
//MyFunction Is Function that you Define
});
newThread.Start();
newThread.Join();
return response;
}
The BackgroundWorker is nice when developing for Windows Forms.
Say you wanted to pass a simple class back and forth:
class Anything {
// Number and Text are for instructional purposes only
public int Number { get; set; }
public string Text { get; set; }
// Data can be any object - even another class
public object Data { get; set; }
}
I wrote up a short class that does the following:
Create or Clear a list
Start a loop
In loop, create a new item for the list
In loop, create a thread
In loop, send the item as a parameter to the thread
In loop, start the thread
In loop, add thread to list to watch
After loop, join each thread
After all joins have completed, display the results
From inside the thread routine:
Call lock so that only 1 thread can enter this routine at a time (others have to wait)
Post information about the item.
Modify the item.
When the thread completes, the data is displayed on the console.
Adding a delegate can be useful for posting your data directly back to your main thread, but you may need to use Invoke if some of the data items are not thread safe.
class AnyTask {
private object m_lock;
public AnyTask() {
m_lock = new object();
}
// Something to use the delegate
public event MainDelegate OnUpdate;
public void Test_Function(int count) {
var list = new List<Thread>(count);
for (var i = 0; i < count; i++) {
var thread = new Thread(new ParameterizedThreadStart(Thread_Task));
var item = new Anything() {
Number = i,
Text = String.Format("Test_Function #{0}", i)
};
thread.Start(item);
list.Add(thread);
}
foreach (var thread in list) {
thread.Join();
}
}
private void MainUpdate(Anything item, bool original) {
if (OnUpdate != null) {
OnUpdate(item, original);
}
}
private void Thread_Task(object parameter) {
lock (m_lock) {
var item = (Anything)parameter;
MainUpdate(item, true);
item.Text = String.Format("{0}; Thread_Task #{1}", item.Text, item.Number);
item.Number = 0;
MainUpdate(item, false);
}
}
}
To test this, create a little Console Application, and put this in the Program.cs file:
// A delegate makes life simpler
delegate void MainDelegate(Anything sender, bool original);
class Program {
private const int COUNT = 15;
private static List<Anything> m_list;
static void Main(string[] args) {
m_list = new List<Anything>(COUNT);
var obj = new AnyTask();
obj.OnUpdate += new MainDelegate(ThreadMessages);
obj.Test_Function(COUNT);
Console.WriteLine();
foreach (var item in m_list) {
Console.WriteLine("[Complete]:" + item.Text);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
private static void ThreadMessages(Anything item, bool original) {
if (original) {
Console.WriteLine("[main method]:" + item.Text);
} else {
m_list.Add(item);
}
}
}
Here is a screenshot of what I got with this:
I hope others can understand what I've tried to explain.
I enjoy working on threads and using delegates. They make C# a lot of fun.
Appendix: For VB Coders
I wanted to see what was involved in writing the code above as a VB Console Application. The conversion involved a few things I didn't expect, so I will update this thread here for those wanting to know how to thread in VB.
Imports System.Threading
Delegate Sub MainDelegate(sender As Anything, original As Boolean)
Class Main
Private Const COUNT As Integer = 15
Private Shared m_list As List(Of Anything)
Public Shared Sub Main(args As String())
m_list = New List(Of Anything)(COUNT)
Dim obj As New AnyTask()
AddHandler obj.OnUpdate, New MainDelegate(AddressOf ThreadMessages)
obj.Test_Function(COUNT)
Console.WriteLine()
For Each item As Anything In m_list
Console.WriteLine("[Complete]:" + item.Text)
Next
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
Private Shared Sub ThreadMessages(item As Anything, original As Boolean)
If original Then
Console.WriteLine("[main method]:" + item.Text)
Else
m_list.Add(item)
End If
End Sub
End Class
Class AnyTask
Private m_lock As Object
Public Sub New()
m_lock = New Object()
End Sub
' Something to use the delegate
Public Event OnUpdate As MainDelegate
Public Sub Test_Function(count As Integer)
Dim list As New List(Of Thread)(count)
For i As Int32 = 0 To count - 1
Dim thread As New Thread(New ParameterizedThreadStart(AddressOf Thread_Task))
Dim item As New Anything()
item.Number = i
item.Text = String.Format("Test_Function #{0}", i)
thread.Start(item)
list.Add(thread)
Next
For Each thread As Thread In list
thread.Join()
Next
End Sub
Private Sub MainUpdate(item As Anything, original As Boolean)
RaiseEvent OnUpdate(item, original)
End Sub
Private Sub Thread_Task(parameter As Object)
SyncLock m_lock
Dim item As Anything = DirectCast(parameter, Anything)
MainUpdate(item, True)
item.Text = [String].Format("{0}; Thread_Task #{1}", item.Text, item.Number)
item.Number = 0
MainUpdate(item, False)
End SyncLock
End Sub
End Class
Class Anything
' Number and Text are for instructional purposes only
Public Property Number() As Integer
Get
Return m_Number
End Get
Set(value As Integer)
m_Number = value
End Set
End Property
Private m_Number As Integer
Public Property Text() As String
Get
Return m_Text
End Get
Set(value As String)
m_Text = value
End Set
End Property
Private m_Text As String
' Data can be anything or another class
Public Property Data() As Object
Get
Return m_Data
End Get
Set(value As Object)
m_Data = value
End Set
End Property
Private m_Data As Object
End Class
Threads do not really have return values. However, if you create a delegate, you can invoke it asynchronously via the BeginInvoke method. This will execute the method on a thread pool thread. You can get any return value from such as call via EndInvoke.
Example:
static int GetAnswer() {
return 42;
}
...
Func<int> method = GetAnswer;
var res = method.BeginInvoke(null, null); // provide args as needed
var answer = method.EndInvoke(res);
GetAnswer will execute on a thread pool thread and when completed you can retrieve the answer via EndInvoke as shown.
class Program
{
static void Main(string[] args)
{
string returnValue = null;
new Thread(
() =>
{
returnValue =test() ;
}).Start();
Console.WriteLine(returnValue);
Console.ReadKey();
}
public static string test()
{
return "Returning From Thread called method";
}
}
A simple solution is to pass a parameter by ref to the function that is running in the thread and change its value in the thread.
// create a list of threads
List<Thread> threads = new List<Thread>();
//declare the ref params
bool is1 = false;
bool is2 = false;
threads.Add(new Thread(() => myFunction(someVar, ref is1)));
threads.Add(new Thread(() => myFunction(someVar, ref is2)));
threads.ForEach(x => x.Start());
// wait for threads to finish
threads.ForEach(x => x.Join());
//check the ref params
if (!is1)
{
//do something
}
if (!is2)
{
//do somethign else
}
If you can't change the function that is running in the tread, you can wrap it another function:
bool theirFunction(var someVar){
return false;
}
void myFunction(var someVar ref bool result){
result = theirFunction(myVar);
}
class Program
{
public static void ActionResultPrint(string i)
{
Console.WriteLine(i);
}
static void Main(string[] args)
{
var tl = new List<Thread>();
tl.Add(new Thread(() => Run(10, ActionResultPrint)));
tl.Add(new Thread(() => Run(20, ActionResultPrint)));
tl.ForEach(x => x.Start());
tl.ForEach(x => x.Join());
}
public static void Run(int j, Action<string> action)
{
string rvalue = string.Empty;
for (int i = 0; i <= j; i++)
{
Thread.Sleep(100);
rvalue = i.ToString();
Console.WriteLine(rvalue);
}
action($#"output {j}");
}
}
when threads are used , value can be passed and returned in following ways:
int value = -1;
Thread t1 = new Thread(() => { value = compute(a); });
t1.Start();
if(value!=-1)
{...}
public int compute(int[] a1)
{
//...code logic
return -1;
}
I'm no kind of expert in threading, that's why I did it like this:
I created a Settings file and
Inside the new thread:
Setting.Default.ValueToBeSaved;
Setting.Default.Save();
Then I pick up that value whenever I need it.

TaskFactory, Starting a new Task when one ends

I have found many methods of using the TaskFactory but I could not find anything about starting more tasks and watching when one ends and starting another one.
I always want to have 10 tasks working.
I want something like this
int nTotalTasks=10;
int nCurrentTask=0;
Task<bool>[] tasks=new Task<bool>[nThreadsNum];
for (int i=0; i<1000; i++)
{
string param1="test";
string param2="test";
if (nCurrentTask<10) // if there are less than 10 tasks then start another one
tasks[nCurrentThread++] = Task.Factory.StartNew<bool>(() =>
{
MyClass cls = new MyClass();
bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish
return bRet;
});
// How can I stop the for loop until a new task is finished and start a new one?
}
Check out the Task.WaitAny method:
Waits for any of the provided Task objects to complete execution.
Example from the documentation:
var t1 = Task.Factory.StartNew(() => DoOperation1());
var t2 = Task.Factory.StartNew(() => DoOperation2());
Task.WaitAny(t1, t2)
I would use a combination of Microsoft's Reactive Framework (NuGet "Rx-Main") and TPL for this. It becomes very simple.
Here's the code:
int nTotalTasks=10;
string param1="test";
string param2="test";
IDisposable subscription =
Observable
.Range(0, 1000)
.Select(i => Observable.FromAsync(() => Task.Factory.StartNew<bool>(() =>
{
MyClass cls = new MyClass();
bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish
return bRet;
})))
.Merge(nTotalTasks)
.ToArray()
.Subscribe((bool[] results) =>
{
/* Do something with the results. */
});
The key part here is the .Merge(nTotalTasks) which limits the number of concurrent tasks.
If you need to stop the processing part way thru just call subscription.Dispose() and everything gets cleaned up for you.
If you want to process each result as they are produced you can change the code from the .Merge(...) like this:
.Merge(nTotalTasks)
.Subscribe((bool result) =>
{
/* Do something with each result. */
});
This should be all you need, not complete, but all you need to do is wait on the first to complete and then run the second.
Task.WaitAny(task to wait on);
Task.Factory.StartNew()
Have you seen the BlockingCollection class? It allows you to have multiple threads running in parallel and you can wait from results from one task to execute another. See more information here.
The answer depends on whether the tasks to be scheduled are CPU or I/O bound.
For CPU-intensive work I would use Parallel.For() API setting the number of thread/tasks through MaxDegreeOfParallelism property of ParallelOptions
For I/O bound work the number of concurrently executing tasks can be significantly larger than the number of available CPUs, so the strategy is to rely on async methods as much as possible, which reduces the total number of threads waiting for completion.
How can I stop the for loop until a new task is finished and start a
new one?
The loop can be throttled by using await:
static void Main(string[] args)
{
var task = DoWorkAsync();
task.Wait();
// handle results
// task.Result;
Console.WriteLine("Done.");
}
async static Task<bool> DoWorkAsync()
{
const int NUMBER_OF_SLOTS = 10;
string param1="test";
string param2="test";
var results = new bool[NUMBER_OF_SLOTS];
AsyncWorkScheduler ws = new AsyncWorkScheduler(NUMBER_OF_SLOTS);
for (int i = 0; i < 1000; ++i)
{
await ws.ScheduleAsync((slotNumber) => DoWorkAsync(i, slotNumber, param1, param2, results));
}
ws.Complete();
await ws.Completion;
}
async static Task DoWorkAsync(int index, int slotNumber, string param1, string param2, bool[] results)
{
results[slotNumber] = results[slotNumber} && await Task.Factory.StartNew<bool>(() =>
{
MyClass cls = new MyClass();
bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish
return bRet;
}));
}
A helper class AsyncWorkScheduler uses TPL.DataFlow components as well as Task.WhenAll():
class AsyncWorkScheduler
{
public AsyncWorkScheduler(int numberOfSlots)
{
m_slots = new Task[numberOfSlots];
m_availableSlots = new BufferBlock<int>();
m_errors = new List<Exception>();
m_tcs = new TaskCompletionSource<bool>();
m_completionPending = 0;
// Initial state: all slots are available
for(int i = 0; i < m_slots.Length; ++i)
{
m_slots[i] = Task.FromResult(false);
m_availableSlots.Post(i);
}
}
public async Task ScheduleAsync(Func<int, Task> action)
{
if (Volatile.Read(ref m_completionPending) != 0)
{
throw new InvalidOperationException("Unable to schedule new items.");
}
// Acquire a slot
int slotNumber = await m_availableSlots.ReceiveAsync().ConfigureAwait(false);
// Schedule a new task for a given slot
var task = action(slotNumber);
// Store a continuation on the task to handle completion events
m_slots[slotNumber] = task.ContinueWith(t => HandleCompletedTask(t, slotNumber), TaskContinuationOptions.ExecuteSynchronously);
}
public async void Complete()
{
if (Interlocked.CompareExchange(ref m_completionPending, 1, 0) != 0)
{
return;
}
// Signal the queue's completion
m_availableSlots.Complete();
await Task.WhenAll(m_slots).ConfigureAwait(false);
// Set completion
if (m_errors.Count != 0)
{
m_tcs.TrySetException(m_errors);
}
else
{
m_tcs.TrySetResult(true);
}
}
public Task Completion
{
get
{
return m_tcs.Task;
}
}
void SetFailed(Exception error)
{
lock(m_errors)
{
m_errors.Add(error);
}
}
void HandleCompletedTask(Task task, int slotNumber)
{
if (task.IsFaulted || task.IsCanceled)
{
SetFailed(task.Exception);
return;
}
if (Volatile.Read(ref m_completionPending) == 1)
{
return;
}
// Release a slot
m_availableSlots.Post(slotNumber);
}
int m_completionPending;
List<Exception> m_errors;
BufferBlock<int> m_availableSlots;
TaskCompletionSource<bool> m_tcs;
Task[] m_slots;
}

Is it possible always to force a new thread with Task?

I am trying to create a new thread each time Task.Factory.StartNew is called. The question is how to run the code bellow without throwing the exception:
static void Main(string[] args)
{
int firstThreadId = 0;
Task.Factory.StartNew(() => firstThreadId = Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 100; i++)
{
Task.Factory.StartNew(() =>
{
while (true)
{
Thread.Sleep(1000);
if (firstThreadId == Thread.CurrentThread.ManagedThreadId)
throw new Exception("The first thread is reused.");
}
});
}
Console.Read();
}
EDIT: the new code if you comment the first for statement there is no problem. But if you have it, WOW, the message "Thread reused" is written to the console. Can you explain that because I am really confused.
static void Main(string[] args)
{
ConcurrentDictionary<int, int> startedThreads = new ConcurrentDictionary<int, int>();
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(() =>
{
Task.Factory.StartNew(() =>
{
startedThreads.AddOrUpdate(Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.ManagedThreadId, (a, b) => b);
}, TaskCreationOptions.LongRunning);
for (int j = 0; j < 100; j++)
{
Task.Factory.StartNew(() =>
{
while (true)
{
Thread.Sleep(10);
if (startedThreads.ContainsKey(
Thread.CurrentThread.ManagedThreadId))
Console.WriteLine("Thread reused");
}
}, TaskCreationOptions.LongRunning);
}
});
}
Console.Read();
}
If you specify TaskCreationOptions.LongRunning when starting the task, that provides a hint to the scheduler, which the default scheduler takes as an indicator to create a new thread for the task.
It's only a hint - I'm not sure I'd rely on it... but I haven't seen any counterexamples using the default scheduler.
Adding to Jon Skeet's answer, if you want to guarantee that a new thread is created every time, you can write your own TaskScheduler that creates a new thread.
Try this:
var taskCompletionSource = new TaskCompletionSource<bool>();
Thread t = new Thread(() =>
{
try
{
Operation();
taskCompletionSource.TrySetResult(true);
}
catch (Exception e)
{
taskCompletionSource.TrySetException(e);
}
});
void Operation()
{
// Some work in thread
}
t.Start();
await taskCompletionSource.Task;
You also can write extension methods for Action, Func and so on.
For example:
public static Task RunInThread(
this Action action,
Action<Thread> initThreadAction = null)
{
TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
Thread thread = new Thread(() =>
{
try
{
action();
taskCompletionSource.TrySetResult(true);
}
catch (Exception e)
{
taskCompletionSource.TrySetException(e);
}
});
initThreadAction?.Invoke(thread);
thread.Start();
return taskCompletionSource.Task;
}
or
public static Task<TResult> RunInThread<T1, T2, TResult>(
this Func<T1, T2, TResult> function,
T1 param1,
T2 param2,
Action<Thread> initThreadAction = null)
{
TaskCompletionSource<TResult> taskCompletionSource = new TaskCompletionSource<TResult>();
Thread thread = new Thread(() =>
{
try
{
TResult result = function(param1, param2);
taskCompletionSource.TrySetResult(result);
}
catch (Exception e)
{
taskCompletionSource.TrySetException(e);
}
});
initThreadAction?.Invoke(thread);
thread.Start();
return taskCompletionSource.Task;
}
and use it like that:
var result = await some_function.RunInThread(param1, param2).ConfigureAwait(true);
Hello and thank you all for the answers. You all got +1. All suggested solution did not work for my case. The problem is that when you sleep a thread it will be reused at some point of time. The people above suggested:
using LongRunning => This will not work if you have nested/child
tasks
custom task scheduler => I tried to write my own and also tried this
ThreadPerTaskScheduler which also di not work.
using pure threads => Still failing...
you could also check this project at Multithreading.Scheduler github
My solution
I don't like it but it works. Basically I block the thread so it cannot be reused. Bellow are the extension methods and a working example. Again, thank you.
https://gist.github.com/4150635
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public static class ThreadExtensions
{
/// <summary>
/// Blocks the current thread for a period of time so that the thread cannot be reused by the threadpool.
/// </summary>
public static void Block(this Thread thread, int millisecondsTimeout)
{
new WakeSleepClass(millisecondsTimeout).SleepThread();
}
/// <summary>
/// Blocks the current thread so that the thread cannot be reused by the threadpool.
/// </summary>
public static void Block(this Thread thread)
{
new WakeSleepClass().SleepThread();
}
/// <summary>
/// Blocks the current thread for a period of time so that the thread cannot be reused by the threadpool.
/// </summary>
public static void Block(this Thread thread, TimeSpan timeout)
{
new WakeSleepClass(timeout).SleepThread();
}
class WakeSleepClass
{
bool locked = true;
readonly TimerDisposer timerDisposer = new TimerDisposer();
public WakeSleepClass(int sleepTime)
{
var timer = new Timer(WakeThread, timerDisposer, sleepTime, sleepTime);
timerDisposer.InternalTimer = timer;
}
public WakeSleepClass(TimeSpan sleepTime)
{
var timer = new Timer(WakeThread, timerDisposer, sleepTime, sleepTime);
timerDisposer.InternalTimer = timer;
}
public WakeSleepClass()
{
var timer = new Timer(WakeThread, timerDisposer, Timeout.Infinite, Timeout.Infinite);
timerDisposer.InternalTimer = timer;
}
public void SleepThread()
{
while (locked)
lock (timerDisposer) Monitor.Wait(timerDisposer);
locked = true;
}
public void WakeThread(object key)
{
locked = false;
lock (key) Monitor.Pulse(key);
((TimerDisposer)key).InternalTimer.Dispose();
}
class TimerDisposer
{
public Timer InternalTimer { get; set; }
}
}
}
class Program
{
private static readonly Queue<CancellationTokenSource> tokenSourceQueue = new Queue<CancellationTokenSource>();
static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSourceQueue.Enqueue(tokenSource);
ConcurrentDictionary<int, int> startedThreads = new ConcurrentDictionary<int, int>();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Task.Factory.StartNew(() =>
{
startedThreads.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ManagedThreadId, (a, b) => b);
for (int j = 0; j < 50; j++)
Task.Factory.StartNew(() => startedThreads.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ManagedThreadId, (a, b) => b));
for (int j = 0; j < 50; j++)
{
Task.Factory.StartNew(() =>
{
while (!tokenSource.Token.IsCancellationRequested)
{
if (startedThreads.ContainsKey(Thread.CurrentThread.ManagedThreadId)) Console.WriteLine("Thread reused");
Thread.CurrentThread.Block(10);
if (startedThreads.ContainsKey(Thread.CurrentThread.ManagedThreadId)) Console.WriteLine("Thread reused");
}
}, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)
.ContinueWith(task =>
{
WriteExceptions(task.Exception);
Console.WriteLine("-----------------------------");
}, TaskContinuationOptions.OnlyOnFaulted);
}
Thread.CurrentThread.Block();
}, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)
.ContinueWith(task =>
{
WriteExceptions(task.Exception);
Console.WriteLine("-----------------------------");
}, TaskContinuationOptions.OnlyOnFaulted);
}
Console.Read();
}
private static void WriteExceptions(Exception ex)
{
Console.WriteLine(ex.Message);
if (ex.InnerException != null)
WriteExceptions(ex.InnerException);
}
}
}
Just start threads with new Thread() and then Start() them
static void Main(string[] args)
{
ConcurrentDictionary<int, int> startedThreads = new ConcurrentDictionary<int, int>();
for (int i = 0; i < 10; i++)
{
new Thread(() =>
{
new Thread(() =>
{
startedThreads.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ManagedThreadId, (a, b) => b);
}).Start();
for (int j = 0; j < 100; j++)
{
new Thread(() =>
{
while (true)
{
Thread.Sleep(10);
if (startedThreads.ContainsKey(Thread.CurrentThread.ManagedThreadId))
Console.WriteLine("Thread reused");
}
}).Start();
}
}).Start();
}
Console.Read();
}
Tasks are supposed to be managed by the scheduler. The whole idea of Tasks is that the runtime will decide when a new thread is needed. On the other hand if you do need different threads chances are something else in the code is wrong like overdependency on Thread.Sleep() or thread local storage.
As pointed out you can create your own TaskScheduler and use tasks to create threads but then why use Tasks to begin with?
Here is a custom TaskScheduler that executes the tasks on a dedicated thread per task:
public class ThreadPerTask_TaskScheduler : TaskScheduler
{
protected override void QueueTask(Task task)
{
var thread = new Thread(() => TryExecuteTask(task));
thread.IsBackground = true;
thread.Start();
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return TryExecuteTask(task);
}
protected override IEnumerable<Task> GetScheduledTasks() { yield break; }
}
Usage example:
var parallelOptions = new ParallelOptions()
{
MaxDegreeOfParallelism = 3,
TaskScheduler = new ThreadPerTask_TaskScheduler()
};
Parallel.ForEach(Enumerable.Range(1, 10), parallelOptions, item =>
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}" +
$" [{Thread.CurrentThread.ManagedThreadId}]" +
$" Processing #{item}" +
(Thread.CurrentThread.IsBackground ? ", Background" : "") +
(Thread.CurrentThread.IsThreadPoolThread ? ", ThreadPool" : ""));
Thread.Sleep(1000); // Simulate CPU-bound work
});
Output:
20:38:56.770 [4] Processing #3, Background
20:38:56.770 [5] Processing #2, Background
20:38:56.770 [1] Processing #1
20:38:57.782 [1] Processing #4
20:38:57.783 [8] Processing #5, Background
20:38:57.783 [7] Processing #6, Background
20:38:58.783 [1] Processing #7
20:38:58.783 [10] Processing #8, Background
20:38:58.787 [9] Processing #9, Background
20:38:59.783 [1] Processing #10
Try it on Fiddle.
This custom TaskScheduler allows the current thread to participate in the computations too. This is demonstrated in the above example by the thread [1] processing the items #1, #4, #7 and #10. If you don't want this to happen, just replace the code inside the TryExecuteTaskInline with return false;.
Another example, featuring the Task.Factory.StartNew method. Starting 100 tasks on 100 different threads:
var oneThreadPerTask = new ThreadPerTask_TaskScheduler();
Task[] tasks = Enumerable.Range(1, 100).Select(_ =>
{
return Task.Factory.StartNew(() =>
{
Thread.Sleep(1000); // Simulate long-running work
}, default, TaskCreationOptions.None, oneThreadPerTask);
}).ToArray();
In this case the current thread is not participating in the work, because all tasks are started behind the scenes by invoking their Start method, and not the
RunSynchronously.

Problem with Invoke to parallelize foreach

I have a problem with using System.Threading.Tasks.Parallel.ForEach. The body foreach progressBar want to update.
But Invoke method sometimes freeze.
I attach the code to the form which is prograssbar and Buton.
private void button1_Click(object sender, EventArgs e)
{
DateTime start = DateTime.Now;
pforeach();
Text = (DateTime.Now - start).ToString();
}
private void pforeach()
{
int[] intArray = new int[60];
int totalcount = intArray.Length;
object lck = new object();
System.Threading.Tasks.Parallel.ForEach<int, int>(intArray,
() => 0,
(x, loop, count) =>
{
int value = 0;
System.Threading.Thread.Sleep(100);
count++;
value = (int)(100f / (float)totalcount * (float)count);
Set(value);
return count;
},
(x) =>
{
});
}
private void Set(int i)
{
if (this.InvokeRequired)
{
var result = Invoke(new Action<int>(Set), i);
}
else
progressBar1.Value = i;
}
Sometimes it passes without a problem, but usually it freeze on
var result = Invoke (new Action <int> (Set), i).
Try to kick me in the problem.
Thank you.
Your problem is that Invoke (and queueing a Task to the UI TaskScheduler) both require the UI thread to be processing its message loop. However, it is not. It is still waiting for the Parallel.ForEach loop to complete. This is why you see a deadlock.
If you want the Parallel.ForEach to run without blocking the UI thread, wrap it into a Task, as such:
private TaskScheduler ui;
private void button1_Click(object sender, EventArgs e)
{
ui = TaskScheduler.FromCurrentSynchronizationContext();
DateTime start = DateTime.Now;
Task.Factory.StartNew(pforeach)
.ContinueWith(task =>
{
task.Wait(); // Ensure errors are propogated to the UI thread.
Text = (DateTime.Now - start).ToString();
}, ui);
}
private void pforeach()
{
int[] intArray = new int[60];
int totalcount = intArray.Length;
object lck = new object();
System.Threading.Tasks.Parallel.ForEach<int, int>(intArray,
() => 0,
(x, loop, count) =>
{
int value = 0;
System.Threading.Thread.Sleep(100);
count++;
value = (int)(100f / (float)totalcount * (float)count);
Task.Factory.StartNew(
() => Set(value),
CancellationToken.None,
TaskCreationOptions.None,
ui).Wait();
return count;
},
(x) =>
{
});
}
private void Set(int i)
{
progressBar1.Value = i;
}
I was looking at how I did this and this change may help you:
In my constructor I have this line:
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Then I do this:
private void changeProgressBar()
{
(new Task(() =>
{
mainProgressBar.Value++;
mainProgressTextField.Text = mainProgressBar.Value + " of " + mainProgressBar.Maximum;
})).Start(uiScheduler);
}
This gets rid of needing to use Invoke, and if you use the Task method then it may solve your problem.
I think these were all in System.Threading.Tasks;

How to call the method in thread with arguments and return some value

I like to call the method in thread with arguments and return some value here example
class Program
{
static void Main()
{
Thread FirstThread = new Thread(new ThreadStart(Fun1));
Thread SecondThread = new Thread(new ThreadStart(Fun2));
FirstThread.Start();
SecondThread.Start();
}
public static void Fun1()
{
for (int i = 1; i <= 1000; i++)
{
Console.WriteLine("Fun1 writes:{0}", i);
}
}
public static void Fun2()
{
for (int i = 1000; i >= 6; i--)
{
Console.WriteLine("Fun2 writes:{0}", i);
}
}
}
I know this above example run successfully but if method fun1 like this
public int fun1(int i,int j)
{
int k;
k=i+j;
return k;
}
then how can I call this in thread?
You should be able to use an anonymous method or lambda to provide full static checking:
Thread FirstThread = new Thread(() => Fun1(5, 12));
or if you want to do something with the result:
Thread FirstThread = new Thread(() => {
int i = Fun1(5, 12);
// do something with i
});
but note that this "do something" still runs in the context of the new thread (but with access to the other variables in the outer method (Main) courtesy of "captured variables").
If you have C# 2.0 (and not above), then:
Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); });
and
Thread FirstThread = new Thread((ThreadStart)delegate {
int i = Fun1(5, 12);
// do something with i
});
This may be another approach. Here input is passed as parameterized Thread and return type is passed in the delegate event, so that when the thread complete that will call the Delegate. This will be fine to get result when the thread completes.
public class ThreadObject
{
public int i;
public int j;
public int result;
public string Name;
}
public delegate void ResultDelegate(ThreadObject threadObject);
public partial class Form1 : Form
{
public event ResultDelegate resultDelete;
public Form1()
{
InitializeComponent();
resultDelete += new ResultDelegate(resultValue);
}
void resultValue(ThreadObject threadObject)
{
MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result);
}
private void button1_Click(object sender, EventArgs e)
{
ThreadObject firstThreadObject = new ThreadObject();
firstThreadObject.i = 0;
firstThreadObject.j = 100;
firstThreadObject.Name = "First Thread";
Thread firstThread = new Thread(Fun);
firstThread.Start(firstThreadObject);
ThreadObject secondThreadObject = new ThreadObject();
secondThreadObject.i = 0;
secondThreadObject.j = 200;
secondThreadObject.Name = "Second Thread";
Thread secondThread = new Thread(Fun);
secondThread.Start(secondThreadObject);
}
private void Fun(object parameter)
{
ThreadObject threadObject = parameter as ThreadObject;
for (; threadObject.i < threadObject.j; threadObject.i++)
{
threadObject.result += threadObject.i;
Thread.Sleep(10);
}
resultValue(threadObject);
}
}
I like Mark Gravell's answer. You can pass your result back out to the main thread with just a little modification:
int fun1, fun2;
Thread FirstThread = new Thread(() => {
fun1 = Fun1(5, 12);
});
Thread SecondThread = new Thread(() => {
fun2 = Fun2(2, 3);
});
FirstThread.Start();
SecondThread.Start();
FirstThread.Join();
SecondThread.Join();
Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2);
There is much simpler way to execute function in separate thread:
// Create function delegate (it can be any delegate)
var FunFunc = new Func<int, int, int>(fun1);
// Start executing function on thread pool with parameters
IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null);
// Do some stuff
// Wait for asynchronous call completion and get result
int Result = FunFunc.EndInvoke(FunFuncResult);
This function will be executed on thread pool thread, and that logic is completely transparent to your application.
An in general, I suggest to execute such small tasks on thread pool instead of dedicated thread.
You can use the ParameterizedThreadStart overload on the Thread constructor. It allows you to pass an Object as a parameter to your thread method. It's going to be a single Object parameter, so I usually create a parameter class for such threads.. This object can also store the result of the thread execution, that you can read after the thread has ended.
Don't forget that accessing this object while the thread is running is possible, but is not "thread safe". You know the drill :)
Here's an example:
void Main()
{
var thread = new Thread(Fun);
var obj = new ThreadObject
{
i = 1,
j = 15,
};
thread.Start(obj);
thread.Join();
Console.WriteLine(obj.result);
}
public static void Fun(Object obj)
{
var threadObj = obj as ThreadObject;
threadObj.result = threadObj.i + threadObj.j;
}
public class ThreadObject
{
public int i;
public int j;
public int result;
}
For some alternatives; currying:
static ThreadStart CurryForFun(int i, int j)
{ // also needs a target object if Fun1 not static
return () => Fun1(i, j);
}
Thread FirstThread = new Thread(CurryForFun(5, 12));
or write your own capture-type (this is broadly comparable to what the compiler does for you when you use anon-methods / lambdas with captured variables, but has been implemented differently):
class MyCaptureClass
{
private readonly int i, j;
int? result;
// only available after execution
public int Result { get { return result.Value; } }
public MyCaptureClass(int i, int j)
{
this.i = i;
this.j = j;
}
public void Invoke()
{ // will also need a target object if Fun1 isn't static
result = Fun1(i, j);
}
}
...
MyCaptureClass capture = new MyCaptureClass(5, 12);
Thread FirstThread = new Thread(capture.Invoke);
// then in the future, access capture.Result
try backgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx you can pass value to the DoWork event with DoWorkEventArgs and retrive value in the RunWorkerCompleted.

Categories