Strange case involving TaskContinuationOptions.RunContinuationsAsynchronously - c#

async void Main()
{
T0.TT();
}
private class T0
{
[ThreadStatic] private static int test;
public static async void TT()
{
test = 4;
var continuation = new System.Threading.Tasks.TaskCompletionSource<int>(System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously);
var th = new Thread(() => { Thread.Sleep(500); Console.WriteLine(test); test = 3; continuation.TrySetResult(5); test = 7; });
th.Start();
Console.WriteLine(await continuation.Task);
Console.WriteLine(test);
}
}
Output:
0
5
3
So without the System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously this was written to demonstrate the rest of the async method runs on the thread created by new Thread(). However with System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously it still somehow finds that specific [ThreadStatic] value that is set in the newly created thread (thus can't be a TaskScheduler thread) and cleared as soon as TrySetResult returns.
What the hey? How is this happening?

You should be passing TaskCreationOptions.RunContinuationsAsynchronously, not TaskContinuationOptions.RunContinuationsAsynchronously.
Passing TaskContinuationOptions.RunContinuationsAsynchronously will call the overload that takes an object parameter, treating it as a "state" object and not as a flag controlling the TCS behavior.

Related

Instance Variable

Please consider code below. Each time I run the code, output will be always 0 and 3. I am sure it has something to do with single instance but didn't have any explanation why this is happening. It will be great if you can help me understand this. Thank you for your help.
Is this happening because variable points to a different location in heap each time we initialize it ?
public class Helper
{
List<int> list = new List<int>();
public List<int> GetList
{
get
{
return list;
}
}
public async Task<bool> Process()
{
await Task.Delay(1);
//sleep this thread for 6 seconds
Thread.Sleep(6000);
//When I debug, both of the thread adds into the list
//but first thread always have zero element on this list, if it adds to the list then where it is getting lost ?
//not sure why ? Has to do something with the variable below _confighelper
//but why it behaves likes this ? what would be the best explanation?
//where this variable is getting lost ?
list.Add(1);
list.Add(2);
list.Add(3);
return true;
}
}
public class RunOp
{
//Has to do something with single instance
Helper _configHelper;
public async Task Run()
{
_configHelper = new Helper();
var val = await _configHelper.Process();
Console.WriteLine(_configHelper.GetList.Count);
}
}
class Program
{
static void Main(string[] args)
{
RunOp op = new RunOp();
Task.Factory.StartNew(async () =>
{
await op.Run();
});
Thread.Sleep(4000);
//Start another thread after 4 seconds
Task.Factory.StartNew(async () =>
{
await op.Run();
});
Console.ReadLine();
}
}
This is a simple case of thread safety, and this is not thread safe
The problem is RunOp has an internal Helper, which gets overwritten and showing (what seems) inconsistent results because of the thread sleeps and delays.
Here is a thread safe version
public class RunOp
{
private SemaphoreSlim slim = new SemaphoreSlim(1,1);
//Has to do something with single instance
Helper _configHelper;
public async Task Run()
{
await slim.WaitAsync();
_configHelper = new Helper();
var val = await _configHelper.Process();
Console.WriteLine(_configHelper.GetList.Count);
slim.Release();
}
// or
public async Task Run()
{
Helper configHelper = new Helper();
var val = await configHelper.Process();
Console.WriteLine(configHelper.GetList.Count);
}
}
I know this is only an academic problem, but this really should be refactored and thought through again

Throwing Thread was being Aborted exception while running test method in c#

I have a method Create which performs a Db insert. Also I have a delegate Sampledelegate where the Create method is called in seperate thread.
public delegate int Sampledelegate(int num);
class Activity
{
public int AddNum(int num)
{
Console.WriteLine("Value of Num: {0}", num);
Object obj = new object();
Thread newThread = new Thread(this.Create);
newThread.Start(obj);
return num;
}
void Create(object obj)
{
try
{
Memo memo = (Memo)obj;
//DAO initialization which internally includes extracting
connection to DB
WorkpacketDao workPacketDao = new WorkpacketDao();
workPacketDao.CreateMemo(memo);
}
catch (Exception ex)
{
Logger.Info(ex.Message);
}
}
}
Now I have written a test case to check whether it is working fine or not.
So my test case is
public void AddNumTest()
{
AddNum(1);
Sampledelegate samdel = new Sampledelegate(AddNum);
}
When I run this test case I am getting an exception : Thread was being aborted in create method.
But when I run the delegate AddNum through another method like main method, I am not getting this exception .
Calling AddNum through another method:
static void Main(string[] args)
{
Activity activity = new Activity();
activity.AddNum(1);
Sampledelegate samdel = new Sampledelegate(activity.AddNum);
Console.ReadKey();
}
Can anyone please help me with this, Why I am getting this exception when I run through test case?
Thanks.

C# - Start new thread calling parameter method [duplicate]

How do you start a thread with parameters in C#?
One of the 2 overloads of the Thread constructor takse a ParameterizedThreadStart delegate which allows you to pass a single parameter to the start method. Unfortunately though it only allows for a single parameter and it does so in an unsafe way because it passes it as object. I find it's much easier to use a lambda expression to capture the relevant parameters and pass them in a strongly typed fashion.
Try the following
public Thread StartTheThread(SomeType param1, SomeOtherType param2) {
var t = new Thread(() => RealStart(param1, param2));
t.Start();
return t;
}
private static void RealStart(SomeType param1, SomeOtherType param2) {
...
}
Yep :
Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);
You can use lambda expressions
private void MyMethod(string param1,int param2)
{
//do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();
this is so far the best answer i could find, it's fast and easy.
Simple way using lambda like so..
Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();
OR you could even delegate using ThreadStart like so...
private void DoSomething(int param1, string param2)
{
//DO SOMETHING...
ThreadStart ts = delegate
{
if (param1 > 0) DoSomethingElse(param2, "param3");
};
new Thread(ts).Start();
//DO SOMETHING...
}
OR using .NET 4.5+ even cleaner like so..
private void DoSomething(int param1, string param2)
{
//DO SOMETHING..
void ts()
{
if (param1 > 0) DoSomethingElse(param2, "param3");
}
new Thread(ts).Start();
//DO SOMETHING..
}
Thread thread = new Thread(Work);
thread.Start(Parameter);
private void Work(object param)
{
string Parameter = (string)param;
}
The parameter type must be an object.
EDIT:
While this answer isn't incorrect I do recommend against this approach. Using a lambda expression is much easier to read and doesn't require type casting. See here: https://stackoverflow.com/a/1195915/52551
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
t.Start("My Parameter");
}
static void ThreadMethod(object parameter)
{
// parameter equals to "My Parameter"
}
}
As has already been mention in various answers here, the Thread class currently (4.7.2) provides several constructors and a Start method with overloads.
These relevant constructors for this question are:
public Thread(ThreadStart start);
and
public Thread(ParameterizedThreadStart start);
which either take a ThreadStart delegate or a ParameterizedThreadStart delegate.
The corresponding delegates look like this:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
So as can be seen, the correct constructor to use seems to be the one taking a ParameterizedThreadStart delegate so that some method conform to the specified signature of the delegate can be started by the thread.
A simple example for instanciating the Thread class would be
Thread thread = new Thread(new ParameterizedThreadStart(Work));
or just
Thread thread = new Thread(Work);
The signature of the corresponding method (called Work in this example) looks like this:
private void Work(object data)
{
...
}
What is left is to start the thread. This is done by using either
public void Start();
or
public void Start(object parameter);
While Start() would start the thread and pass null as data to the method, Start(...) can be used to pass anything into the Work method of the thread.
There is however one big problem with this approach:
Everything passed into the Work method is cast into an object. That means within the Work method it has to be cast to the original type again like in the following example:
public static void Main(string[] args)
{
Thread thread = new Thread(Work);
thread.Start("I've got some text");
Console.ReadLine();
}
private static void Work(object data)
{
string message = (string)data; // Wow, this is ugly
Console.WriteLine($"I, the thread write: {message}");
}
Casting is something you typically do not want to do.
What if someone passes something else which is not a string? As this seems not possible at first (because It is my method, I know what I do or The method is private, how should someone ever be able to pass anything to it?) you may possibly end up with exactly that case for various reasons. As some cases may not be a problem, others are. In such cases you will probably end up with an InvalidCastException which you probably will not notice because it simply terminates the thread.
As a solution you would expect to get a generic ParameterizedThreadStart delegate like ParameterizedThreadStart<T> where T would be the type of data you want to pass into the Work method. Unfortunately something like this does not exist (yet?).
There is however a suggested solution to this issue. It involves creating a class which contains both, the data to be passed to the thread as well as the method that represents the worker method like this:
public class ThreadWithState
{
private string message;
public ThreadWithState(string message)
{
this.message = message;
}
public void Work()
{
Console.WriteLine($"I, the thread write: {this.message}");
}
}
With this approach you would start the thread like this:
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);
thread.Start();
So in this way you simply avoid casting around and have a typesafe way of providing data to a thread ;-)
I was having issue in the passed parameter.
I passed integer from a for loop to the function and displayed it , but it always gave out different results. like (1,2,2,3) (1,2,3,3) (1,1,2,3) etc with ParametrizedThreadStart delegate.
this simple code worked as a charm
Thread thread = new Thread(Work);
thread.Start(Parameter);
private void Work(object param)
{
string Parameter = (string)param;
}
The ParameterizedThreadStart takes one parameter. You can use that to send one parameter, or a custom class containing several properties.
Another method is to put the method that you want to start as an instance member in a class along with properties for the parameters that you want to set. Create an instance of the class, set the properties and start the thread specifying the instance and the method, and the method can access the properties.
You could use a ParametrizedThreadStart delegate:
string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);
You can use the BackgroundWorker RunWorkerAsync method and pass in your value.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
int x = 10;
Thread t1 =new Thread(new ParameterizedThreadStart(order1));
t1.IsBackground = true;//i can stope
t1.Start(x);
Thread t2=new Thread(order2);
t2.Priority = ThreadPriority.Highest;
t2.Start();
Console.ReadKey();
}//Main
static void order1(object args)
{
int x = (int)args;
for (int i = 0; i < x; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}
static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}`enter code here`
}
}
I propose using Task<T>instead of Thread; it allows multiple parameters and executes really fine.
Here is a working example:
public static void Main()
{
List<Task> tasks = new List<Task>();
Console.WriteLine("Awaiting threads to finished...");
string par1 = "foo";
string par2 = "boo";
int par3 = 3;
for (int i = 0; i < 1000; i++)
{
tasks.Add(Task.Run(() => Calculate(par1, par2, par3)));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("All threads finished!");
}
static bool Calculate1(string par1, string par2, int par3)
{
lock(_locker)
{
//...
return true;
}
}
// if need to lock, use this:
private static Object _locker = new Object();"
static bool Calculate2(string par1, string par2, int par3)
{
lock(_locker)
{
//...
return true;
}
}
A very simple and convenient way using lambda expression can be like this:
Thread thread = new Thread( (param) => {
string name = param as string;
// rest of code goes here.
});
thread.Start("MyName");
This way a lambda expression can have parameters and run inline code in a separate thread.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
int x = 10;
Thread t1 =new Thread(new ParameterizedThreadStart(order1));
t1.Start(x);
Thread t2=new Thread(order2);
t2.Priority = ThreadPriority.Highest;
t2.Start();
Console.ReadKey();
}//Main
static void order1(object args)
{
int x = (int)args;
for (int i = 0; i < x; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}
static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}
}
}

producer-consumer with a resource

I'm trying to implement the producer/consumer pattern with a set of resources, so each thread has one resource associated with it. For example, I may have a queue of tasks where each task requires a StreamWriter to write its result. Each task also has to have parameters passed to it.
I started with Joseph Albahari's implementation (see below for my modified version).
I replaced the queue of Action with a queue of Action<T> where T is the resource, and pass the resource associated with the thread to the Action. But, this leaves me with the problem of how to pass parameters to the Action. Obviously, the Action must be replaced with a delegate but this leaves the problem of how to pass parameters when tasks are enqueued (from outside the ProducerConsumerQueue class). Any ideas on how to do this?
class ProducerConsumerQueue<T>
{
readonly object _locker = new object();
Thread[] _workers;
Queue<Action<T>> _itemQ = new Queue<Action<T>>();
public ProducerConsumerQueue(T[] resources)
{
_workers = new Thread[resources.Length];
// Create and start a separate thread for each worker
for (int i = 0; i < resources.Length; i++)
{
Thread thread = new Thread(() => Consume(resources[i]));
thread.SetApartmentState(ApartmentState.STA);
_workers[i] = thread;
_workers[i].Start();
}
}
public void Shutdown(bool waitForWorkers)
{
// Enqueue one null item per worker to make each exit.
foreach (Thread worker in _workers)
EnqueueItem(null);
// Wait for workers to finish
if (waitForWorkers)
foreach (Thread worker in _workers)
worker.Join();
}
public void EnqueueItem(Action<T> item)
{
lock (_locker)
{
_itemQ.Enqueue(item); // We must pulse because we're
Monitor.Pulse(_locker); // changing a blocking condition.
}
}
void Consume(T parameter)
{
while (true) // Keep consuming until
{ // told otherwise.
Action<T> item;
lock (_locker)
{
while (_itemQ.Count == 0) Monitor.Wait(_locker);
item = _itemQ.Dequeue();
}
if (item == null) return; // This signals our exit.
item(parameter); // Execute item.
}
}
}
The type T in ProducerConsumerQueue<T> doesn't have to be your resource it can be a composite type that contains your resource. With .NET4 the easiest way to do this is with Tuple<StreamWriter, YourParameterType>. The produce/consumer queue just eats and spits out T so in your Action<T> you can just use properties to get the resource and the parameter. If you are using Tuple you would use Item1 to get the resource and Item2 to get the parameter.
If you are not use .NET4, the process is similar but you just create your own class:
public class WorkItem<T>
{
private StreamWriter resource;
private T parameter;
public WorkItem(StreamWriter resource, T parameter)
{
this.resource = resource;
this.parameter = parameter;
}
public StreamWriter Resource { get { return resource; } }
public T Parameter { get { return parameter; } }
}
In fact, making it generic may be overdesigning for your situation. You can just define T to be the type you want it to be.
Also, for reference, there are new ways to do multi-threading included in .NET4 that may applicable to your use case such as concurrent queues and the Parallel Task Library. They can also be combined with traditional approaches such as semaphores.
Edit:
Continuing with this approach, here is a small sample class that demonstrates using:
a semaphore to control access to a limited resource
a concurrent queue to manage that resource safely between threads
task management using the Task Parallel Library
Here is the Processor class:
public class Processor
{
private const int count = 3;
private ConcurrentQueue<StreamWriter> queue = new ConcurrentQueue<StreamWriter>();
private Semaphore semaphore = new Semaphore(count, count);
public Processor()
{
// Populate the resource queue.
for (int i = 0; i < count; i++) queue.Enqueue(new StreamWriter("sample" + i));
}
public void Process(int parameter)
{
// Wait for one of our resources to become free.
semaphore.WaitOne();
StreamWriter resource;
queue.TryDequeue(out resource);
// Dispatch the work to a task.
Task.Factory.StartNew(() => Process(resource, parameter));
}
private Random random = new Random();
private void Process(StreamWriter resource, int parameter)
{
// Do work in background with resource.
Thread.Sleep(random.Next(10) * 100);
resource.WriteLine("Parameter = {0}", parameter);
queue.Enqueue(resource);
semaphore.Release();
}
}
and now we can use the class like this:
var processor = new Processor();
for (int i = 0; i < 10; i++)
processor.Process(i);
and no more than three tasks will be scheduled at the same time, each with their own StreamWriter resource which is recycled.

Unit testing asynchronous function

In the following code sample I have an Async Calculator class. This is injected with an ICalc, which will be a syncronous calculator. I use dependency injecting and mock the ICalc because this resembles my true scenario, though I guess the mocking isn't really of relevance to the question. The AsyncCalc has a function which will call another function asynchronously - taking a callback as parameter. And when the async function call finishes the callback will be triggered with the result.
Now I want to test my asynchronous function - checking that the callback is triggered with the expected parameter. This code seems to work. However, I feel like it might blow up at any time - and my concern is race condition of the callback to finish before the function ends and the test is terminated - as this will be run in a separate thread.
My question now is if I'm on the right track unit testing the async function, or if anyone can help me get on the right track..? What would feel better is if I could ensure that the callback is triggered right away - and preferably on the same thread I guess? Can/Should it be done?
public interface ICalc
{
int AddNumbers(int a, int b);
}
public class AsyncCalc
{
private readonly ICalc _calc;
public delegate void ResultProcessor(int result);
public delegate int AddNumbersAsyncCaller(int a, int b);
public AsyncCalc(ICalc calc)
{
_calc = calc;
}
public void AddNumbers(int a, int b, ResultProcessor resultProcessor)
{
var caller = new AddNumbersAsyncCaller(_calc.AddNumbers);
caller.BeginInvoke(a, b, new AsyncCallback(AddNumbersCallbackMethod), resultProcessor);
}
public void AddNumbersCallbackMethod(IAsyncResult ar)
{
var result = (AsyncResult)ar;
var caller = (AddNumbersAsyncCaller)result.AsyncDelegate;
var resultFromAdd = caller.EndInvoke(ar);
var resultProcessor = ar.AsyncState as ResultProcessor;
if (resultProcessor == null) return;
resultProcessor(resultFromAdd);
}
}
[Test]
public void TestingAsyncCalc()
{
var mocks = new MockRepository();
var fakeCalc = mocks.DynamicMock<ICalc>();
using (mocks.Record())
{
fakeCalc.AddNumbers(1, 2);
LastCall.Return(3);
}
var asyncCalc = new AsyncCalc(fakeCalc);
asyncCalc.AddNumbers(1, 2, TestResultProcessor);
}
public void TestResultProcessor(int result)
{
Assert.AreEqual(3, result);
}
You could use a ManualResetEvent to synchronize your threads.
In the following example, the test thread will block on the call to completion.WaitOne().
The callback for the async calculation stores the result and then signals the event by calling completion.Set().
[Test]
public void TestingAsyncCalc()
{
var mocks = new MockRepository();
var fakeCalc = mocks.DynamicMock<ICalc>();
using (mocks.Record())
{
fakeCalc.AddNumbers(1, 2);
LastCall.Return(3);
}
var asyncCalc = new AsyncCalc(fakeCalc);
var completion = new ManualResetEvent(false);
int result = 0;
asyncCalc.AddNumbers(1, 2, r => { result = r; completion.Set(); });
completion.WaitOne();
Assert.AreEqual(3, calcResult);
}
// ** USING AN ANONYMOUS METHOD INSTEAD
// public void TestResultProcessor(int result)
// {
// Assert.AreEqual(3, result);
// }
You could also use a "test runner" class to run the asserts in a loop. The loop would run the asserts in a try/catch. The exception handler would simply try to run the asserts again until a timeout has expired. I recently wrote a blog post about this technique. The example is in groovy, but is applicable to any language. Instead of passing a Closure, you would pass a Action in c#.
http://www.greenmoonsoftware.com/2013/08/asynchronous-functional-testing/

Categories