Threads in c++/cli - multithreading

I have a function that "simulates" chess PGN .txt files.
The function looks like this:
PGNFileEinlesen^ pGN = gcnew PGNFileEinlesen(cBoxDateiNamen->Text);
Simulation::DctFigur = dctFigur;
//reset(Reset.Komplett);
// Den Header in die Textbox schreiben
for each(String^ s in pGN->CsvHeader)
{
rTextBoxZuege->AppendText(s + Environment::NewLine);
}
rTextBoxZuege->AppendText(Environment::NewLine);
// Sleep vor erstem Zug
System::Threading::Thread::Sleep(zeitIntervall);
for (int i = 1; i <= pGN->DtcZuege->Count; i++)
{
// Falls Siegesbedingung oder Spiel vorzeitit beendet: (*)
// 1-0 --> weiss gewinnt
// 0-1 --> schwarz gewinnt
// 1/2-1/2 --> Remi
// * --> Partie ist noch nicht beendet
addTextRichTextbox(i, pGN->DtcZuege[i]->Split(' ')[0]);
if (partieBeendet(pGN->DtcZuege[i]->Split(' ')[0]))
{
return;
}
Simulation::Zug(pGN->DtcZuege[i]->Split(' ')[0], Farbe::Weiss);
try
{
simulationsZug();
}
catch (Exception^ e)
{
Console::WriteLine("SimulationsZug() " + e->Message);
}
System::Threading::Thread::Sleep(zeitIntervall);
this->farbeAmZug = farbeAmZugAendern();
addTextRichTextbox(pGN->DtcZuege[i]->Split(' ')[1]);
if (partieBeendet(pGN->DtcZuege[i]->Split(' ')[1]))
{
btnReset->PerformClick();
return;
}
Simulation::Zug(pGN->DtcZuege[i]->Split(' ')[1], Farbe::Schwarz);
try
{
simulationsZug();
}
catch (Exception^ e)
{
Console::WriteLine("SimulationsZug() " + e->Message);
}
System::Threading::Thread::Sleep(zeitIntervall);
this->farbeAmZug = farbeAmZugAendern();
}
btnReset->Enabled = true;
Now, the problem is, that if I start the simulation, the whole GUI is freezing until the function reaches the end of the for loop.
I tried to create a new thread:
threadSimulation = gcnew Thread(gcnew ThreadStart(this, &Schachfeld::test));
threadSimulation->Start();
but I get the error, that my thread is overlapping with the actual thread because I access controls from the original thread.
(and functions too)
Could somebody explain to me what I should do? I didn't find very much by googling.
Thank you!

Related

Commands not all working in J2ME app

Part of my j2me project involves use of the filesystem, so I'm starting with a simple file browser. The current issue I'm facing is the implementation of the command processor. To wit:
<CODE>
public void commandAction(Command c, Displayable d) {
if (c.getLabel().equals("Exit")) {
notifyDestroyed();
}
// File retrieval code (or call to it) to go here later.
if (c.getLabel().equals("Enter")) {
current_name = getRidOfTrailingSlash(current_name)
+ "/" + mainscreen.getString(mainscreen.getSelectedIndex());
// + "/" + "MemoryCard/";
System.exit(0);
if (! setName(current_name)) {
dirlist = rootlist;
current_name = "/";
}
showDirs();
}
if (c.getLabel().equals("Up Dir")) {
if (current_name.equals("/")) return;
current_name = getRidOfTrailingSlash(current_name);
if (setName(current_name)) current_name = current_fc.getPath();
else current_name = "/";
if (current_name.equals("/")) dirlist = rootlist;
else {
try {
dirlist = current_fc.list();
} catch (IOException ioe) {}
}
showDirs();
}
if (c.getLabel().equals("Create")) {
System.exit(1);
// Create code to be added later
}
if (c.getLabel().equals("Delete")) {
System.exit(2);
// Delete code to be added later
}
} // End of command actions
</CODE>
I am working on debugging the code for "Enter", and plan to write the code for "Create" and "Delete" at a later date. So for now I have them exit to an expected Security exception.
The code that sets up the commands is as follows:
<CODE>
public String getRidOfTrailingSlash(String s) {
if (s.equals("/")) return "";
int len = s.length();
String end = s.substring(len - 1);
if (end.equals("/")) s = s.substring(len - 2);
return s;
}
public List makeFileList(Enumeration names, String[] cmds) {
int i,s,cmdtype;
String c;
List l = new List(current_name, List.EXCLUSIVE);
while (names.hasMoreElements()) {
c = (String) names.nextElement();
l.append(c, null);
}
s = cmds.length;
for (i=0; i<s; i++) {
c = cmds[i];
if (c.equalsIgnoreCase("Exit")) {
cmdtype = Command.EXIT;
} else
if (c.equalsIgnoreCase("Up Dir")) {
cmdtype = Command.BACK;
} else {
cmdtype = Command.BACK;
}
// I've also tried using ITEM, OK, and one or two other
// command types for the default. Same effect.
l.addCommand(new Command(c, cmdtype, 1));
}
return l;
}
private void showDirs() {
String commands[] = { "Enter", "Up Dir", "Create", "Delete", "Exit" };
mainscreen = makeFileList(dirlist, commands);
mainscreen.setCommandListener(this);
Display.getDisplay(this).setCurrent(mainscreen);
}
</CODE>
My current issue is that the commands are not all being executed. "Exit" and "Up Dir" are working properly. However, the other three commands don't function at all in the Emulator. They show up in the menus, but selecting them does absolutely nothing when they should be routing the program flow through the System.exit() calls. If I select any of these any number of times, "Up Dir" and "Exit" still work afterward. Furthermore, the select function in the file list doesn't do anything either.
On the phone that I'm writing this for (An LG Rumor Reflex), the select function (checking and unchecking items in the list) works, as do the commands "Create", "Delete", "Up Dir", and "Exit". However, the "Enter" command doesn't even appear in the menu!
What am I doing wrong, and why the different behavior on the phone versus the Emulator?

C++/CLI code doesn't enter .then part of the create_task function

This is the code that I have:
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
XTRACE(L"=========================================will start onNavigated ");
auto mediaCapture = ref new Windows::Media::Capture::MediaCapture();
m_mediaCaptureMgr = mediaCapture;
IAsyncAction ^asyncAction = m_mediaCaptureMgr->InitializeAsync();
try
{
create_task(asyncAction).then([this](task<void> initTask)
{
XTRACE(L"=========================================will start onNavigated 2");
try
{
initTask.get();
auto mediaCapture = m_mediaCaptureMgr.Get();
if (mediaCapture->MediaCaptureSettings->VideoDeviceId != nullptr && mediaCapture->MediaCaptureSettings->AudioDeviceId != nullptr)
{
String ^fileName;
fileName = VIDEO_FILE_NAME;
XTRACE(L"=================================Device initialized successful\n");
create_task(KnownFolders::VideosLibrary->CreateFileAsync(fileName, Windows::Storage::CreationCollisionOption::GenerateUniqueName))
.then([this](task<StorageFile^> fileTask)
{
XTRACE(L"=================================Create record file successful\n");
m_recordStorageFile = fileTask.get();
MediaEncodingProfile^ recordProfile = nullptr;
recordProfile = MediaEncodingProfile::CreateMp4(Windows::Media::MediaProperties::VideoEncodingQuality::Auto);
stream = ref new InMemoryRandomAccessStream();
return m_mediaCaptureMgr->StartRecordToStreamAsync(recordProfile, stream);
}).then([this](task<void> recordTask)
{
try
{
recordTask.get();
XTRACE(L"=================================Start Record successful\n");
}
catch (Exception ^e)
{
XTRACE(L"======ERRROR is : %d", e);
}
});
}
else
{
XTRACE(L"=================================No VideoDevice/AudioDevice Found\n");
}
XTRACE(L"=================================WILL EXIT \n");
}
catch (Exception ^ e)
{
XTRACE(L"============================================ERROR IS: %d\n", e);
}
}
);
}
catch (Exception ^ e)
{
XTRACE(L"============================================before create task ERROR IS: %d\n", e);
}
XTRACE(L"=================================SLEEP 20000====================================\n");
std::chrono::milliseconds dura(20000);
std::this_thread::sleep_for(dura);
XTRACE(L"=================================TIME ENDED====================================\n");
// stop device detection
try
{
XTRACE(L"=================================Stopping Record\n");
create_task(m_mediaCaptureMgr->StopRecordAsync())
.then([this](task<void> recordTask)
{
try
{
recordTask.get();
XTRACE(L"=================================Stop record successful: %d\n", stream->Size);
}
catch (Exception ^e)
{
XTRACE(L"=================================ERROR while stoping 2: %d\n", e);
}
});
}
catch (Exception ^e)
{
XTRACE(L"=================================ERROR try catch 3 stoping: %d\n", e);
}
CloseHandle(ghEvent);
// destruct the device manager
XTRACE(L"=====================================================================END\n");
}
In the log I see:
=========================================will start onNavigated
And then directly:
=====================================================================
=================================SLEEP 20000====================================
What is strange is that I had this code in a unittest and it worked, I created a new windows phone project with a UI and it doesn't work
Apparently it was because of the ThreadSleep:
std::chrono::milliseconds dura(20000);
std::this_thread::sleep_for(dura);
In the library project where I was working I was using a different sleep, provided by the library, and that would work. So this was the line that would cause the application to block itself.
I worked my way around this by including 2 buttons in the app, for the start and stop recording.

CyclicBarrier code not working?

I got CyclicBarrier code from oracle page to understand it more. I modified it and now having one doubt.
Below code doesn't terminate but If I uncomment Thread.sleep condition, It works fine.
import java.util.Arrays;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Solver {
final int N;
final float[][] data;
boolean done = false;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) {
myRow = row;
}
public void run() {
while (!done) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
System.out.println("Run finish for " + Thread.currentThread().getName());
}
private void processRow(int row) {
float[] rowData = data[row];
for (int i = 0; i < rowData.length; i++) {
rowData[i] = 1;
}
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
done = true;
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
barrier = new CyclicBarrier(N, new Runnable() {
public void run() {
for (int i = 0; i < data.length; i++) {
System.out.println("Data " + Arrays.toString(data[i]));
}
System.out.println("Completed:");
}
});
for (int i = 0; i < N; ++i)
new Thread(new Worker(i), "Thread "+ i).start();
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
float[][] matrix = new float[5][5];
Solver solver = new Solver(matrix);
}
}
Why Thread.sleep is required in above code?
I've not run your code but there may be a race condition, here is a scenario that reveals it:
you start the first thread, it runs during a certain amount of time sufficient for it to finish the processRow method call so it sets done to true and then waits on the barrier,
the other threads start but they see that all is "done" so they don't enter the loop and they'll never wait on the barrier, and end directly
the barrier will never be activated as only one of the N threads has reached it
deadlock
Why it is working with the sleep:
when one of the thread starts to sleep it lets the other threads work before marking the work as "done"
the other threads have enough time to work and can themselves reach the barrier
2 seconds is largely enough for 5 threads to end a processing that should not last longer than 10ms
But note that if your system is ovrerloaded it could too deadlock:
the first thread starts to sleep
the OS scheduler lets another application work during more than 2 seconds
the OS scheduler comes back to your application and the threads scheduler chooses the first thread again and lets it terminate, setting done to true
and here again the first scenario => deadlock too
And a possible solution (sorry not tested):
change your while loops for do/while loops:
do
{
processRow(myRow);
...
}
while (!done);

How to grab value from a thread?

Hi i am trying to grab a value from my threading but it seem work not so find to me course i found that my code structure are unstable enough..here is my code i name my thread class as "clsThreadCount" and below is my implementation
public volatile bool Grab = false;
public volatile int count = 0;
public void Initialization(int i)
{
count = i;
}
public void Play()
{
Grab = false;
_shouldStop = false;
ThreadTest();
}
public void Stop()
{
_shouldStop = true;
workerThread.Join(1);
workerThread.Abort();
}
private void ThreadTest()
{
workerThread = new Thread(DoWork);
workerThread.Start();
while (!workerThread.IsAlive) ;
}
private void DoWork()
{
try
{
while (!_shouldStop)
{
if (Grab)
{
count++;
Grab = false;
}
}
}
catch (Exception)
{
Play();
}
finally
{
}
}
when my program(main menu) are starting to run i will trigger the initialize function at pass the parameter as 7
ObjThreadCount.Initialization(7); // count = 7
ObjThreadCount.Play(); // the thread are running
ObjThreadCount.Grab = true; // the grab equal to true, count++ are trigger
Thread.Sleep(100); // wait awhile
lblResult.Text = ObjThreadCount.count.ToString(); // sometime i can get count++ result (e.g. 8)
ObjThreadCount.Stop(); // thread stop
sometime my program can able to get a right counting from the thread but sometime are not.
i realize at my while loop implementation there are something are missing..
something like waitone or waitautoevent..can i ignore Thread.Sleep(100) ?? what are the suitable code should i add in the while loop ?
Please help me~ :S
** sorry in the first upload i forgot to write down "volatile" into the variable
thank you..
If C# (and C and java, and probably C++), you need to declare _shouldStop and Grab as volatile.

C# powershell output reader iterator getting modified when pipeline closed and disposed

I'm calling a powershell script from C#. The script is pretty small and is "gps;$host.SetShouldExit(9)", which list process, and then send back an exit code to be captured by the PSHost object.
The problem I have is when the pipeline has been stopped and disposed, the output reader PSHost collection still seems to be written to, and is filling up. So when I try and copy it to my own output object, it craps out with a OutOfMemoryException when I try to iterate over it. Sometimes it will except with a Collection was modified message. Here is the code.
private void ProcessAndExecuteBlock(ScriptBlock Block)
{
Collection<PSObject> PSCollection = new Collection<PSObject>();
Collection<Object> PSErrorCollection = new Collection<Object>();
Boolean Error = false;
int ExitCode=0;
//Send for exection.
ExecuteScript(Block.Script);
// Process the waithandles.
while (PExecutor.PLine.PipelineStateInfo.State == PipelineState.Running)
{
// Wait for either error or data waithandle.
switch (WaitHandle.WaitAny(PExecutor.Hand))
{
// Data
case 0:
Collection<PSObject> data = PExecutor.PLine.Output.NonBlockingRead();
if (data.Count > 0)
{
for (int cnt = 0; cnt <= (data.Count-1); cnt++)
{
PSCollection.Add(data[cnt]);
}
}
// Check to see if the pipeline has been closed.
if (PExecutor.PLine.Output.EndOfPipeline)
{
// Bring back the exit code.
ExitCode = RHost.ExitCode;
}
break;
case 1:
Collection<object> Errordata = PExecutor.PLine.Error.NonBlockingRead();
if (Errordata.Count > 0)
{
Error = true;
for (int count = 0; count <= (Errordata.Count - 1); count++)
{
PSErrorCollection.Add(Errordata[count]);
}
}
break;
}
}
PExecutor.Stop();
// Create the Execution Return block
ExecutionResults ER = new ExecutionResults(Block.RuleGuid,Block.SubRuleGuid, Block.MessageIdentfier);
ER.ExitCode = ExitCode;
// Add in the data results.
lock (ReadSync)
{
if (PSCollection.Count > 0)
{
ER.DataAdd(PSCollection);
}
}
// Add in the error data if any.
if (Error)
{
if (PSErrorCollection.Count > 0)
{
ER.ErrorAdd(PSErrorCollection);
}
else
{
ER.InError = true;
}
}
// We have finished, so enque the block back.
EnQueueOutput(ER);
}
and this is the PipelineExecutor class which setups the pipeline for execution.
public class PipelineExecutor
{
private Pipeline pipeline;
private WaitHandle[] Handles;
public Pipeline PLine
{
get { return pipeline; }
}
public WaitHandle[] Hand
{
get { return Handles; }
}
public PipelineExecutor(Runspace runSpace, string command)
{
pipeline = runSpace.CreatePipeline(command);
Handles = new WaitHandle[2];
Handles[0] = pipeline.Output.WaitHandle;
Handles[1] = pipeline.Error.WaitHandle;
}
public void Start()
{
if (pipeline.PipelineStateInfo.State == PipelineState.NotStarted)
{
pipeline.Input.Close();
pipeline.InvokeAsync();
}
}
public void Stop()
{
pipeline.StopAsync();
}
}
An this is the DataAdd method, where the exception arises.
public void DataAdd(Collection<PSObject> Data)
{
foreach (PSObject Ps in Data)
{
Data.Add(Ps);
}
}
I put a for loop around the Data.Add, and the Collection filled up with 600k+ so feels like the gps command is still running, but why. Any ideas.
Thanks in advance.
Found the problem. Named the resultant collection and the iterator the same, so as it was iterating, it was adding to the collection, and back into the iterator, and so forth. Doh!.

Resources