We have a piece of code that previously worked fine and now it gets stuck, the problem seems to be runtime updates or something like it maybe?
We launch a subthread that shows a Form Dialog and gets a value, this value is returned to the main thread by a static variable in an static class and in that statement the thread gets stuck and visual studio doesn't say anything about what's happening... is there another way to return the value (in some cases there are more than one string to return)
We need to do this way specifically because of how the software we do the add-on programs for work.
Example code:
public static Cons
{
public static string inputvalue;
}
public static Funs
{
public static string GetValueString()
{
Thread threadx = new Thread(GetValueStringx);
threadx.SetApartmentState(ApartmentState.STA);
threadx.Start();
if (threadx.Join(new TimeSpan(0, 3, 0)))
{
return ComprobarLicencia(Cons.inputvalue);
}
/*because the subthread is stuck the wait time (3mins) is always
reached and the code continues here, not getting the input value :/ */
try
{
threadx.Abort();
}
catch
{
}
return "";
}
public static string GetValueStringx()
{
WindowWrapper window = new WindowWrapper(Fun.GetForegroundWindow());
FormInput formlicencia = new FormLicencia();
formlicencia.ShowDialog(window);
Cons.inputvalue = formlicencia.inputvalue; //thread gets stuck here
/*even if i comment all the above lines and i put
directly Cons.inputvalue="valx"; it gets stuck too :s */
}
}
In the end I solved it using this response in this question. Is there some way to give credit to that user? If not i would give the anwser or upvotes to someone that can explain why the subthread gets stuck accesing the static variable...
Related
I have a particular string (actually a RSAParameter but I can convert it to string) that I need to keep "saved" in an MVC app without actually saving it. Considering how MVC works I think that the only solution (if there is any) to do this in the way that I want to do it is to create a thread and keep it alive holding the information that I need. That thread should die when I ask for that information again or when certain amount of time has passed.
So, I thought of the following
public string GetPublicString()
{
string PublicString = "MyPublicString";
string PrivateString = "MyPrivateString";
Thread thread = new Thread(PrivateStringHolder);
thread.Start(PrivateString);
return PublicString;
}
public void PrivateStringHolder(object state)
{
string PrivateString = (string)state;
// Something that keeps this thread alive for 30 seconds
// Something that keeps this thread alive until it's called
}
public GetPrivateString()
{
// Something that retrieves the PrivateString inside PrivateStringHolder
}
I don't know if I'm thinking correctly... I never worked with threads before so I'm asking for your help. Anyone knows how to code something that keeps my thread alive for 30 seconds or until it gets called from the "GetPrivateString" method, and how to make that call from the "GetPrivateString" method to retrieve the "PrivateString" inside the thread?
I red that I can use ManualResetEvent, so maybe the "... or until it gets called from the GetPrivateString..." could be solved doing this:
public string GetPublicString()
{
string PublicString = "MyPublicString";
string PrivateString = "MyPrivateString";
Thread thread = new Thread(PrivateStringHolder);
thread.Start(PrivateString);
return PublicString;
}
ManualResetEvent mre = new ManualResetEvent();
public void PrivateStringHolder(object state)
{
string PrivateString = (string)state;
// Something that keeps this thread alive for 30 seconds
mre.WaitOne();
}
public string GetPrivateString()
{
// Something that retrieves the PrivateString inside PrivateStringHolder
mre.Set();
return PrivateString; // Assuming that I saved the private string in the PrivateString var
}
I'll appreciate any help. Thanks!
I'm writing a program that will analyze changes in the stock market.
Every time the candles on the stock charts are updated, my algorithm scans every chart for certain pieces of data. I've noticed that this process is taking about 0.6 seconds each time, freezing my application. Its not getting stuck in a loop, and there are no other problems like exception errors slowing it down. It just takes a bit of time.
To solve this, I'm trying to see if I can thread the algorithm.
In order to call the algorithm to check over the charts, I have to call this:
checkCharts.RunAlgo();
As threads need an object, I'm trying to figure out how to run the RunAlgo(), but I'm not having any luck.
How can I have a thread run this method in my checkCharts object? Due to back propagating data, I can't start a new checkCharts object. I have to continue using that method from the existing object.
EDIT:
I tried this:
M4.ALProj.BotMain checkCharts = new ALProj.BotMain();
Thread algoThread = new Thread(checkCharts.RunAlgo);
It tells me that the checkCharts part of checkCharts.RunAlgo is gives me, "An object reference is required for the non-static field, method, or property "M4.ALProj.BotMain"."
In a specific if statement, I was going to put the algoThread.Start(); Any idea what I did wrong there?
The answer to your question is actually very simple:
Thread myThread = new Thread(checkCharts.RunAlgo);
myThread.Start();
However, the more complex part is to make sure that when the method RunAlgo accesses variables inside the checkCharts object, this happens in a thread-safe manner.
See Thread Synchronization for help on how to synchronize access to data from multiple threads.
I would rather use Task.Run than Thread. Task.Run utilizes the ThreadPool which has been optimized to handle various loads effectively. You will also get all the goodies of Task.
await Task.Run(()=> checkCharts.RunAlgo);
Try this code block. Its a basic boilerplate but you can build on and extend it quite easily.
//If M4.ALProj.BotMain needs to be recreated for each run then comment this line and uncomment the one in DoRunParallel()
private static M4.ALProj.BotMain checkCharts = new M4.ALProj.BotMain();
private static object SyncRoot = new object();
private static System.Threading.Thread algoThread = null;
private static bool ReRunOnComplete = false;
public static void RunParallel()
{
lock (SyncRoot)
{
if (algoThread == null)
{
System.Threading.ThreadStart TS = new System.Threading.ThreadStart(DoRunParallel);
algoThread = new System.Threading.Thread(TS);
}
else
{
//Recieved a recalc call while still calculating
ReRunOnComplete = true;
}
}
}
public static void DoRunParallel()
{
bool ReRun = false;
try
{
//If M4.ALProj.BotMain needs to be recreated for each run then uncomment this line and comment private static version above
//M4.ALProj.BotMain checkCharts = new M4.ALProj.BotMain();
checkCharts.RunAlgo();
}
finally
{
lock (SyncRoot)
{
algoThread = null;
ReRun = ReRunOnComplete;
ReRunOnComplete = false;
}
}
if (ReRun)
{
RunParallel();
}
}
I am using mvc with Entity framework.
I have one method which is called on button click. method used to get the some value from db. And I am doing some calculation and subtracting the value based on my requirement. At the end I am updating this entity with latest changes.
If I don't have enough value in db for subtraction I want to show the error message to user "Enough value in db". its working fine for single user.
But if that method is called by different user at same time from different-different browser, then its not working.
I have tried with lock the Object or async await but not able to handle this situation. lock is not working on event which is fired by different-2 browser at same time.
Code:
public async Task SaveContainerRoutes(List<ContainerRouteVM> lstCRoute, int cid)
{
//my code
}
Lock code:
public ActionResult SaveContainerRoutes(List<ContainerRouteVM> lstCRoute, int cid)
{
try
{
ContainerRouteBL bl = new ContainerRouteBL();
lock (bl)
{
string note = bl.SaveContainerRoutes(lstCRoute, cid);
}
}
catch (Exception ex)
{
return Json(new { success = false, message = ex.Message });
}
}
Please help. Thanks in advance.
Declare this line in class level
private static Object thisLock = new Object();
use thislock in method
public async Task SaveContainerRoutes(List<ContainerRouteVM> lstCRoute, int cid)
{
lock(thisLock)
{
//place use code
}
}
I have 2 threads to are triggered at the same time and run in parallel. These 2 threads are going to be manipulating a string value, but I want to make sure that there are no data inconsistencies. For that I want to use a lock with Monitor.Pulse and Monitor.Wait. I used a method that I found on another question/answer, but whenever I run my program, the first thread gets stuck at the Monitor.Wait level. I think that's because the second thread has already "Pulsed" and "Waited". Here is some code to look at:
string currentInstruction;
public void nextInstruction()
{
Action actions = {
fetch,
decode
}
Parallel.Invoke(actions);
_pc++;
}
public void fetch()
{
lock(irLock)
{
currentInstruction = "blah";
GiveTurnTo(2);
WaitTurn(1);
}
decodeEvent.WaitOne();
}
public void decode()
{
decodeEvent.Set();
lock(irLock)
{
WaitTurn(2);
currentInstruction = "decoding..."
GiveTurnTo(1);
}
}
// Below are the methods I talked about before.
// Wait for turn to use lock object
public static void WaitTurn(int threadNum, object _lock)
{
// While( not this threads turn )
while (threadInControl != threadNum)
{
// "Let go" of lock on SyncRoot and wait utill
// someone finishes their turn with it
Monitor.Wait(_lock);
}
}
// Pass turn over to other thread
public static void GiveTurnTo(int nextThreadNum, object _lock)
{
threadInControl = nextThreadNum;
// Notify waiting threads that it's someone else's turn
Monitor.Pulse(_lock);
}
Any idea how to get 2 parallel threads to communicate (manipulate the same resources) within the same cycle using locks or anything else?
You want to run 2 peaces of code in parallel, but locking them at start using the same variable?
As nvoigt mentioned, it already sounds wrong. What you have to do is to remove lock from there. Use it only when you are about to access something exclusively.
Btw "data inconsistencies" can be avoided by not having to have them. Do not use currentInstruction field directly (is it a field?), but provide a thread safe CurrentInstruction property.
private object _currentInstructionLock = new object();
private string _currentInstruction
public string CurrentInstruction
{
get { return _currentInstruction; }
set
{
lock(_currentInstructionLock)
_currentInstruction = value;
}
}
Other thing is naming, local variables name starting from _ is a bad style. Some peoples (incl. me) using them to distinguish private fields. Property name should start from BigLetter and local variables fromSmall.
the problem only appears when making Release build and running exe file ( not from visual studio )
in all other combination either it's running from visual studio or running exe everything works fine
I'm running Function Load using backgroundWorker
Load:
while (!Request.GAMELIST.XMLReceived) ;
GameEngine.ParseGameList( Request.GAMELIST.XML );
Request.GAMELIST.XMLReceived = false;
while loop in this fragment works like delay
it should wait till XML is received from server and then continue
but it stucks in above specified situation
if I'll put MessageBox.show("here we go"); after while loop
messageBox will not appear
but if I'll put MessageBox.show("here we go"); before while loop
application will receive data until I click messagebox ok
and then everything will work fine
here is GAMELIST class implementation
public class RequestGAMELIST
{
public string XML;
public bool XMLReceived = false;
public void ParseRequest( string request )
{
int index = request.IndexOf(':') + 2;
XML = request.Substring(index, request.Length - index);
XMLReceived = true;
}
}
please provide help if you can
this is really strange thing which I can't figure out by my self
Thanks.
Yes, this code has very good odds to hang in the Release build. The JIT optimizer doesn't know that the variable might be set to true by code outside of the method. You need to tell it that, like this:
public class RequestGAMELIST
{
public volatile bool XMLReceived = false;
// etc..
}
The volatile keyword ensures that the jitter won't store the variable value in a CPU register.
That solves your problem, it is still not the right way to do it. You should use an AutoResetEvent instead. It ensures that the thread responds to the variable change is quickly as possible. And most importantly, it lets the thread block so it doesn't burn any cpu cycles.
public class RequestGAMELIST
{
public AutoResetEvent XMLReceived = new AutoResetEvent();
public void ParseRequest( string request )
{
int index = request.IndexOf(':') + 2;
XML = request.Substring(index, request.Length - index);
XMLReceived.Set();
}
}
In your thread:
XMLReceived.WaitOne();
GameEngine.ParseGameList( Request.GAMELIST.XML );
This is a bad idea:
while (!Request.GAMELIST.XMLReceived) ;
At least you should be doing something like:
while (!Request.GAMELIST.XMLReceived) {
System.Threading.Thread.Sleep(100); // Don't hog the CPU!
}
Your program runs fine in debug mode perhaps due to certain debug routines added inside the while loop which makes it run slower...