I don't know this is a bug or my mistake?, After Code Virtualization return the empty value.
[assembly: Obfuscation(Feature = "Apply to type *: apply to member * when method or constructor: virtualization", Exclude = false)]
namespace ConsoleApp17
{
class Program
{
private static bool valueWritten = false;
private static int sharedValue = 0;
private static void ThreadOneStart()
{
sharedValue = 1000;
valueWritten = true;
}
private static void ThreadTwoStart()
{
if (valueWritten) Console.Write(sharedValue == 1000 ? "Good" : "Bad");
}
static void Main(string[] args)
{
Thread threadOne = new Thread(ThreadOneStart);
Thread threadTwo = new Thread(ThreadTwoStart);
threadOne.Start();
threadTwo.Start();
threadOne.Join();
threadTwo.Join();
Console.ReadKey();
}
}
}
The given program has a race condition. This implies that the program behavior is undefined. It has nothing to do with Eazfuscator.NET.
Here is the right way do that:
[assembly: Obfuscation(Feature = "Apply to type *: apply to member * when method or constructor: virtualization", Exclude = false)]
class Program
{
private static bool valueWritten = false;
private static int sharedValue = 0;
private static ManualResetEvent ev = new ManualResetEvent(false);
private static void ThreadOneStart()
{
sharedValue = 1000;
valueWritten = true;
ev.Set();
}
private static void ThreadTwoStart()
{
ev.WaitOne();
if (valueWritten) Console.Write(sharedValue == 1000 ? "Good" : "Bad");
}
static void Main(string[] args)
{
Thread threadOne = new Thread(ThreadOneStart);
Thread threadTwo = new Thread(ThreadTwoStart);
threadOne.Start();
threadTwo.Start();
threadOne.Join();
threadTwo.Join();
Console.ReadKey();
}
}
Related
I have a class like this:
class Test {
const int capacity = 100_0000;
private HashSet<int> set = new HashSet<int>(capacity);
public Test() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
set = new HashSet<int>(capacity);
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
set.Add(val);
}
}
The add method is frequently called.
var test = new Test();
Task.Run(() => {
for (int i = 0; i < 100000000; i++) {
test.Add(i);
Thread.SpinWait(5000);
}
});
It doesn't matter whether the data is successfully stored in the set, in this case, is the behavior of the add method consistent with the following code?
class LockTest {
const int capacity = 100_0000;
private HashSet<int> set = new HashSet<int>(capacity);
public LockTest() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
lock (set) set = new HashSet<int>(capacity);
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
lock (set) set.Add(val);
}
}
In my tests, even if there is no lock statement, there is no error. But I don't know what happens at the moment of set = new HashSet<int>(capacity);.
If you change the code to this, what do you think will happen? My guess is that the number you print out will sometimes be the same and other time different. When it is the same, lock(set) has worked, but otherwise it hasn't.
class LockTest {
const int capacity = 100_0000;
private int setCnt = 0;
private object set = new object();
public LockTest() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
lock (set) setCnt++;
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
lock (set) Console.WriteLine($"{setCnt}");
}
}
I have a simple program that simulates my error situation. I have a singleton class that gets a messages from several threads. The execution must be blocked until the function is executed.
class Program
{
private static TestClass test;
static void Main(string[] args)
{
Thread a = new Thread(TestFunctionB);
a.Start();
Thread b = new Thread(TestFunctionB);
b.Start();
}
private static void TestFunctionB()
{
TestClass test = TestClass.Instance;
for (int i = 0; i < 15; i++)
{
test.Handle(i, Thread.CurrentThread.ManagedThreadId);
}
}
}
class TestClass
{
private readonly object _lockObject;
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance ?? (_instance = new TestClass()); }
}
private void RunLocked(Action action)
{
lock (_lockObject)
{
action.Invoke();
}
}
public void Handle(int counter, int threadId)
{
Console.WriteLine("\nThreadId = {0}, counter = {1}\n", threadId, counter);
RunLocked(() =>
{
Console.WriteLine("\nFunction Handle ThreadId = {0}, counter = {1}\n", threadId, counter);
for (int i = 0; i < 30; i++)
{
Console.WriteLine("Funktion Handle threadId = {0}, counter = {1}, i = {2}", threadId, counter, i);
//Thread.Sleep(100);
}
});
Console.WriteLine("\nFunction Handle free ThreadId = {0}, counter = {1}\n", threadId, counter);
}
}
`
I excpect that threads write the output one after another, but in the console the threads outputs are mixed. Is the lock statement not correct?
I don't know if it is your only problem but get { return _instance ?? (_instance = new TestClass()); } is not atomic, you may end up with more than one instance returned.
Use the Lazy<T> class to guarantee that only one instance of the singleton is created.
class TestClass
{
private readonly object _lockObject;
private readonly static Lazy<TestClass> _instance = new Lazy<TestClass>(x=> new TestClass());
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance.Value; }
}
...
}
If you don't have access to .NET 4.0 or newer you will need to lock around your singleton creation.
class TestClass
{
private readonly object _lockObject;
private static readonly object _singletonLock = new Object();
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get
{
if(_instance == null)
{
lock(_singletonLock)
{
if(_instance == null)
{
_instance = new TestClass ();
}
}
}
return _instance;
}
}
...
}
I've created a console application that needs to run in the background of my client application and has to invoke a method after a certain period of time. So far I've tried the below with little success but it doesn't seem to be working.
Furthermore, in a situation where I wanted to use the same timer to invoke more than one method, then what would I do?
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
const bool generate = true;
NewBookingTimer(generate);
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) => NewBooking();
var random = new Random();
int randomNumber = random.Next(0, 500);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void NewBooking()
{
var dbObject = new DbConnect();
dbObject.OpenConnection();
var bookingObject = new GenerateBooking();
bookingObject.NewBooking();
}
}
He he ... Try this:
static void Main(string[] args)
{
const bool generate = true;
NewBookingTimer(generate);
Console.ReadLine();
}
The way you do it, it's waiting for you to enter a line , and then it closes ... so obviously, it won't do anything.
Turning them around, it'll fire your events, and run until you hit Enter :)
Regarding the multiple calls, Do you want it to call Method_A and Methdod_B every time it fires ? You can just have both of them in the event that you raise. Otherwise, do explain better what you want.
Here's your code slightly modified:
static void Main(string[] args)
{
const bool generate = true;
NewBookingTimer(generate);
Console.ReadLine();
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) => NewBooking();
newBookingTimer.Elapsed += (sender, e) => OldBooking();
var random = new Random();
int randomNumber = random.Next(0, 500);
Console.Out.WriteLine("Random = " + randomNumber);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void NewBooking()
{
Console.Out.WriteLine("this is NEW booking");
}
public static void OldBooking()
{
Console.Out.WriteLine("this is OLD booking");
}
and here's the result:
This code executes the 2 methods on the same timer. The only trick was the multi-line lambda timer handler.
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
const bool generate = true;
NewBookingTimer(generate);
Console.WriteLine("Running...");
Console.ReadLine();
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) =>
{
MethodA();
MethodB();
};
var random = new Random();
int randomNumber = random.Next(0, 500);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void MethodA()
{
Console.WriteLine("in method A");
}
public static void MethodB()
{
Console.WriteLine("in method B");
}
}
Is there a way to know which EventWaitHandle was invoked.
i have two custom class with 2 different System Wide Event names.
The reason I had them is to distinguish which function to trigger.
The problem I have right now is how can I distinguish which event was triggered?
EventWaitHandle _ew1 = new EventWaitHandle(false, EventResetMode.AutoReset, "Mode1");
EventWaitHandle _ew2 = new EventWaitHandle(false, EventResetMode.AutoReset, "Mode2");
So if _ew1.Set() is invoked then I need to execute Process1.
If _ew2.Set() is invoked then I need to execute Process2.
Update: Added More Info.
the main thread is a windows service. which is signaled by a web application and a desktop application. so basically the service needs to identify who triggered the event either from a web application or a desktop application if it's a WebAppliation then Execute SP1 else if it's a Windows Application then Execute SP2.
Idea 1
WaitHandle.WaitAny static method returns index of signaled wait handle, so the simplest solution would be to check that index.
Example
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
var handleIndex = WaitHandle.WaitAny(_eventHandles);
Console.WriteLine(handleIndex == 0 ? "Process1" : "Process2");
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
}
Idea 2
You can also use one event handle along with a volatile field that will indicate what conditional statement has been met in order to execute appropriate process after signal.
Example
enum Process
{
Process1,
Process2
}
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent _eventHandle = new AutoResetEvent(false);
private static volatile Process _selectedProcess = Process.Process1;
static void Main()
{
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
_eventHandle.WaitOne();
Console.WriteLine(_selectedProcess == Process.Process1 ? "Process1" : "Process2");
}
}
static void Method()
{
_selectedProcess = _random.Next()%2 == 0 ? Process.Process1 : Process.Process2;
_eventHandle.Set();
}
}
Idea 3
If you are unable to modify external components and you have only event handles, then you may try start new threads for each option and wait there for respective signal in order to perform appropriate operation.
Example
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
Thread[] processThreads = new Thread[2];
processThreads[0] = new Thread(Process1);
processThreads[0].Start();
processThreads[1] = new Thread(Process2);
processThreads[1].Start();
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
static void Process1()
{
while (true)
{
_eventHandles[0].WaitOne();
Console.WriteLine("Process1");
}
}
static void Process2()
{
while (true)
{
_eventHandles[1].WaitOne();
Console.WriteLine("Process2");
}
}
}
Idea 4
If processes require small amount of time, you can use ThreadPool.RegisterWaitForSingleObject Method
Example
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
ThreadPool.RegisterWaitForSingleObject(_eventHandles[0], Process1, null, Timeout.Infinite, false);
ThreadPool.RegisterWaitForSingleObject(_eventHandles[1], Process2, null, Timeout.Infinite, false);
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
static void Process1(object state, bool timedOut)
{
Console.WriteLine("Process1");
}
static void Process2(object state, bool timedOut)
{
Console.WriteLine("Process2");
}
}
Use WaitHandle.WaitAny to wait on multiple event handles. When one or more of the events is set it'll return the index of the event that caused the wait to return.
EventWaitHandle _ew1 = new EventWaitHandle(false, EventResetMode.AutoReset, "Mode1");
EventWaitHandle _ew2 = new EventWaitHandle(false, EventResetMode.AutoReset, "Mode2");
WaitHandle[] handles={_ew1, _ew2};
int index=WaitHandle.WaitAny(handles)
if(index==0)
{
// mode 1
}
else if(index==1)
{
// mode 2
}
An IDEA I can suggests is to create your own EventWaitHandler, that can reuse the name of handler, later this name should be returned from the Wait method and works as an identifier of caller
for this you have to implement your own Wait method (i implemented WaitNew to cater and extend WaitOne)
See the following code for working code:
//Client application environments
public class WindowsApplication
{
public void ExecuteWindowsService()
{
var ws = new WindowsService();
var _eventHandle = new MyEventWaitHandler(false, EventResetMode.AutoReset, "WindowsApplicationMode");
ws.Execute(_eventHandle);
_eventHandle.Set();
}
}
public class WebApplication
{
public void ExecuteWebService()
{
var ws = new WindowsService();
var _eventHandle = new MyEventWaitHandler(false, EventResetMode.AutoReset, "WebApplicationMode");
ws.Execute(_eventHandle);
_eventHandle.Set();
}
}
//Windows Service Environment
public class MyEventWaitHandler : EventWaitHandle
{
public MyEventWaitHandler(bool initialState, EventResetMode mode, string name)
: base(initialState, mode, name)
{
this.EventHandlerName = name;
}
//it should not be set to empty string from external
public string EventHandlerName;
public string WaitNew()
{
if (base.WaitOne())
return EventHandlerName;
else return String.Empty;
}
}
public class WindowsService
{
public void Execute(MyEventWaitHandler _eventHandle)
{
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
string name = _eventHandle.WaitNew();
if (name == "WindowsApplicationMode")
{
//Execute case for first process
}
else if (name == "WebApplicationMode")
{
//Execute case for second process
}
}
}
static void Method()
{
//Some Task
}
}
Let me know if I understand your requirement correct?
Inherit from EventWaitHandle, add a volatile "Caller" property. Every signaller must pass his ID, or Ref.
After Signalled, Interlock check the property.
How about this?
bool signaled = eventWaitHandle.WaitOne(TimeSpan.Zero);
I have this:
public class ServiceLibrary
{
public object result = null;
private bool finished = false;
public void testar()
{
ServiceReference.Service1SoapClient serviceReference = new ServiceReference.Service1SoapClient();
serviceReference.updateUserCompleted += new EventHandler<ServiceReference.updateUserCompletedEventArgs>(serviceReference_updateUserCompleted);
serviceReference.updateUserAsync();
ManualResetEvent m = new ManualResetEvent(true);
}
void serviceReference_updateUserCompleted(object sender, ServiceReference.updateUserCompletedEventArgs e)
{
result = e.Result;
finished = true;
}
}
and outside I have this:
public Home()
{
InitializeComponent();
ServiceLibrary serviceLibrary = new ServiceLibrary();
serviceLibrary.testar();
lblCharName.Text = Convert.ToString(serviceLibrary.result);
}
What should I do to the thread wait, so when I assign the text, it contains the value, please?
Thank you
Could you not use your ManualResetEvent? or create a fresh one.
I believe the ManualResetEvent is thread safe....
public class ServiceLibrary
{
public object result = null;
private bool finished = false;
public ManualResetEvent m;
public void testar()
{
ServiceReference.Service1SoapClient serviceReference = new ServiceReference.Service1SoapClient();
serviceReference.updateUserCompleted += new EventHandler<ServiceReference.updateUserCompletedEventArgs>(serviceReference_updateUserCompleted);
serviceReference.updateUserAsync();
m = new ManualResetEvent(false);
}
void serviceReference_updateUserCompleted(object sender, ServiceReference.updateUserCompletedEventArgs e)
{
result = e.Result;
finished = true;
m.Set();
}
}
public Home()
{
InitializeComponent();
ServiceLibrary serviceLibrary = new ServiceLibrary();
serviceLibrary.testar();
serviceLibrary.m.WaitOne();
lblCharName.Text = Convert.ToString(serviceLibrary.result);
}
Make your ManualResetEvent variable m a member variable of the class.
and inside your threaded method: serviceReference_updateUserCompleted, make sure to call
m.WaitOne();
What about
public class ServiceLibrary
{
public object result = null;
public void testar()
{
var serviceReference = new ServiceReference.Service1SoapClient();
using(var m = new ManualResetEvent(false))
{
Action<object, ServiceReference.updateUserCompletedEventArgs> handler =
(sender, e) =>
{
result = e.Result;
m.Set();
};
serviceReference.updateUserCompleted += handler;
serviceReference.updateUserAsync();
m.WaitOne();
serviceReference.updateUserCompleted -= handler;
}
}
}
I have a similar situation. I use a technique called polling, which is exactly what it sounds like. It may or may not be appropriate for you depending on your situation.
public class ServiceLibrary
{
public object result = null;
private bool finished = false;
public void testar()
{
ServiceReference.Service1SoapClient serviceReference = new ServiceReference.Service1SoapClient();
serviceReference.updateUserCompleted += new EventHandler<ServiceReference.updateUserCompletedEventArgs>(serviceReference_updateUserCompleted);
serviceReference.updateUserAsync();
ManualResetEvent m = new ManualResetEvent(true);
while !finished
Thread.Sleep(100);
doStuffWithResult(result);
}
void serviceReference_updateUserCompleted(object sender, ServiceReference.updateUserCompletedEventArgs e)
{
result = e.Result;
finished = true;
}