I have some application for iOS and android. And I need port it on Windows Phone 8. We have some abstract thread subsystem, and kernel using threads from this subsystem. All this is C++ code.
The first problem I encountered, that run thread on WP8 aka CreateThread. ThreadPool is not a solution for me because application use thread-based parallelism, not a task-based.
My question is how to start thread on WP8? I thied use .NET Thread class, but it doesn't compiling. May be a do something wrong. Please help me by this.
You should be able to use threads in your Windows Phone application, using the System.Threading.Thread class. Creating a thread is straightforward, pass the method you want to execute to the constructor of the thread, then start it:
public void StartThread()
{
var thread = new System.Threading.Thread(DoSomething);
thread.Start();
}
private void DoSomething()
{
// Do stuff
}
you can initialise thread with a method and then start it like
var asd = new System.Threading.Thread(method);
asd.Start();
void method()
{
// Put your Logic Here .....
}
Related
I am implementing a Quarkus server. On server start, a (never ending) background process should be started.
I know I can observe the start event with an #ApplicationScopedbean which implements:
void onStart(#Observes StartupEvent ev).
But what is the best way to start a background process? Are there restrictions?
In J2EE one should not create Threads, but use ManagedExecutorService or an EJB with a #Asynchronous annotated method.
Is there something similar in Quarkus? I only found the scheduler annotations (which are nice, but I want to start a process only once at the beginning).
So can I just create threads? Or just put my infinite code in void onStart(#Observes StartupEvent ev) ?
Thank you
As in EJB you should not do such things with a background process. Such processes that are "out of control" of the framework cause most of time very annoying problems.
The answer is: It depends on what you want to do in that job.
If you want to execute tasks on a regular base you could use timers.
If you want to use it as an asynchronous worker, you can use a message queue.
Both is most easily done with the vert.x integration into Quarkus.
Use #ConsumeEvent to create a queue, use
#Inject
EventBus bus;
bus.send("Example message");
to send messages.
Use #Scheduled to work on regular jobs, like in this example.
If you need to permanently listen to some socket or file it is getting more difficult. Maybe the websockets will be helpful in this case.
The easiest way to start a worker thread is using Vertx#executeBlocking, like this:
#Inject
Vertx vertx;
void foo() {
vertx.<String>executeBlocking(promise -> {
// This code will be executed in a worker thread
System.out.println("Thread: " + Thread.currentThread());
promise.complete("Done");
}, asyncResult -> {
System.out.println(asyncResult.result()); // Done
});
}
If it will be a long running thread maybe it's a good idea not to use the default worker thread pool and create a new one:
...
#PostConstruct
void init() {
this.executor = vertx.createSharedWorkerExecutor("my-worker", 10);
}
void foo() {
executor.<String>executeBlocking(promise -> {
...
}
}
Other way of doing this is using a Verticle.
Have a simple Qt app. Gui thread, creates Dev thread it creates (in its run()) Read thread. Dev and Read threads are my classes inherited from QThread. The Read thread should read data from COM port continuously. An approximate view of Read run is following.
read::run()
{
sp2->clear();
while (DO_EXEC)
{
if (DO_WRITE)
{
// write data to port
}
usleep(500);
ba = sp2->bytesAvailable();
if (ba > 0)
{
int a = sp2->read(&BUF[BUF_END], ba);
// process data
emit sgnl(sendeddata);
}
}
}
To start it I emit signal in GUI that is passed to Dev at it is passed to the following read slot:
read::slot_readStart()
{
// some stuff
if (doStart && !isRunning())
{
sp2 = new QSerialPort(this);
sp2->setPortName("COM3");
sp2->setBaudRate(256000);
sp2->setDataBits(QSerialPort::Data8);
sp2->setStopBits(QSerialPort::OneStop);
sp2->setParity(QSerialPort::NoParity);
sp2->setFlowControl(QSerialPort::NoFlowControl);
sp2->setReadBufferSize(5000);
bool isOpen = sp2->open(QIODevice::ReadWrite);
DO_EXEC = true;
start();
}
}
This works. But, if I place creating and setup and opening serial port to run method, then the port is open, but the bytesAvailable() are always zero? Why it is possible?
Thank you in adcance.
I agree with Orest Hera, in that you are using a "non recommended" way of implementing threads.
You are using inheritance for your thread object.
It is important to understand how QThreads work. The general procedure to using the QThreads is:
Make Object to go into thread, assign no parent
Make thread
Move object into thead using obj->moveToThread(thread)
Connect a signal to a slot in the object that will instatiate the object members (if required)
Start the thread: thread->start()
For example:
MyObj *myObj = new MyObj(0); // 0 = no parent if your object inherits QObject
QThread* thread = new QThread;
myObj->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), myObj, SLOT(run()));
thread->start();
So your object can still have its "run()" function, but it won't be overloading anything.
Also your run() function does not need to be a "forever" loop, it is simply an initialization function (create the serial port or whatever). Then you add other slots for other events, e.g. you can connect the QSerialPort::readyRead() to your "incoming data slot" handler to handle any data received from the serial port.... and so on.
I think this will solve your issues. It is difficult to tell exactly why your serial port does not work in your overloaded "Run()" function because I can't see how you are calling /creating the thread (i.e. the rest of your code) or where DO_EXEC is initialized etc... There is probably some ordering of events or thread ownership issue here.
Note: I am not saying you can't inherit thread class, but if you do that it is so that you create your own custom thread class (to do thread stuff), but not some other class to create a hybrid of thread utility and other stuff. There is a fair amount of information relating to this here (on SO) and on the qt forum if you are interested in the why/how etc... :)
I've been having some issues with threading in monotouch. My app makes use of an external library which I've linked with and it works fine. Because of the nature of the app and the library I have to make all the calls to it on a single separate thread.These calls will generally be :
Random non deterministic caused by user
Every t miliseconds(around 20ms). Like an update function
After reading for a bit I decided to try out NSThread. I've managed to call the Update function by attaching an NSTimer to the thread's RunLoop and it's all working fine. The problem that I'm having now is calling other methods on the same thread. I read somewhere that using PerformSelector on the RunLoop adds the selector invocation to the RunLoop's queue and invokes it when available, which is basically exactly what I need. However the methods that I need to call :
Can have multiple paramteres
Have callbacks, which I need to invoke on the main thread, again with multiple parameters
For the multiple parameters problem I saw that NSInvocation can be a solution, but the life of me I can't figure out how to do it with monotouch and haven't found any relevant examples.
For the actuals calls that I need to make to the library, I tried doing a generic way in which I can call any function I choose via delegates on a particular thread, which sort of works until I'm hit with the multiple parameters and/or callbacks to the main thread again with multiple parameters. Should I maybe just register separate selectors for each (wrapped)function that I need to call from the library?
I'm not hellbent on using this approach, if there is a better way I'm open to it, it's just that after searching for other options I saw that they don't fit my case:
GCD(not even sure I have it in monotouch) spawns threads on it's own whenever necessary. I need a single specific thread to schedule my work on
NSInvocationQueue(which uses GCD internally from what I read) does the same thing.
pThreads, seem overkill and managing them will be a pain(not even sure I can use them in monotouch)
I'm not an iOS developer, the app works fine with monodroid where I had Runnables and Handlers which make life easier :) . Maybe I'm not looking at this the right way and there is a simple solution to this. Any input would be appreciated.
Thanks
UPDATE
I was thinking of doing something along these lines :
Have a simple wrapper :
class SelectorHandler : NSObject
{
public static Selector Selector = new Selector("apply");
private Action execute;
public SelectorHandler(Action ex)
{
this.execute = ex;
}
[Register("apply")]
private void Execute()
{
execute();
}
}
Extend NSThread
public class Daemon : NSThread
{
public void Schedule(Action action)
{
SelectorHandler handler = new SelectorHandler(action);
handler.PerformSelector(SelectorHandler.Selector, this, null, true);
}
}
Then, when I want to call something I can do it like this :
private Daemon daemon;
public void Call_Library_With_Callback(float param, Action<int> callback)
{
daemon.Schedule(() =>
{
int callbackResult = 0;
//Native library calls
//{
// Assign callback result
//}
daemon.InvokeOnMainThread(() =>
{
callback(callbackResult);
});
});
}
I need to update a QGraphicsView with a QGraphicsScene from a thread.
Below is some pseudo'ish code example of what I am doing which is causing me issues (runtime errors).
What am I doing wrong, and how should I be doing it?
Main App:
void Main::startThread()
{
view = new QGraphicsView(...);
thread = new MyThread(...);
connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)), this, SLOT(updateScene(QGraphicsScene*)));
thread->start();
}
void Main::updateScene(QGraphicsScene *scene)
{
view->SetScene(scene);
view->show();
repaint();
}
The Thread:
void MyThread::run()
{
QGraphicsScene *scene = new QGraphicsScene(...);
while(1)
{
//draw stuff on the scene
emit doSceneUpdate(scene);
//some delay
}
Thanks in advance!!!
[edit]
The error is:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread
3e53c0. Receiver '' (of type 'QGraphicsScene') was created in thread 1476cd18", file c:\Qt\qt-everywhere-opensource-src-4.8.2\src\corelib\kernel\qcoreapplication.cpp, line 501
What am I doing wrong, and how should I be doing it?
I think the canonical answer is here -- in a nutshell, the article states that you shouldn't be subclassing QThread, but rather you should use a "bare" (i.e. not-subclassed) QThread object and connect its started() signal to a slot that will then be run in the context of that thread, after the thread starts. That way the object-thread-ownership issues are handled automatically for you.
Note also that threads other than the main Qt thread are generally not allowed to create or interact directly with GUI objects like QGraphicsScene, since doing that would introduce race conditions due to the operations going on simultaneously behind the scenes in Qt's GUI event loop. If you want to use a separate thread, you'll need to keep it away from your GUI objects, and instead just have it emit asynchronous signals and/or send Events to the main/GUI thread to get the main/GUI thread to do the GUI-object updates on its behalf.
The problem is with your connection line. You are connecting a slot to a signal which does not make sense. You should connect the signal from the thread to the slot :
connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)),this, SLOT(updateScene(QGraphicsScene*)));
in
void MyThread::run()
{
QGraphicsScene *scene = new QGraphicsScene(...);
...
}
do you pass this to the constructor of QGraphicsScene()?
That could be one cause of error, since now you are passing a child of MyThread to Main
Try creating a QGraphicsScene object on the stack or with the parent as NULL ( new QGraphicsScene(0) )
I am writing an app that uses the serial port exposed by the SerialPort class in mono. What I have written so far works perfect in windows, however in linux the DataReceived event handler is never entered, so I cannot receive any data form my device. I have declared the event handler as follows:
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
Basically I am exploring good cross-platform options and this is a deal-breaker. Any advise on how to fix this or what is going on?
Edit-
I should also point out that I have tested the serial port and device on linux with other applications and all appears to be working.
Maybe it has changed lastly, but as far as I know, events are not currently implemented in Mono's serial port. You have to make another thread in any flavour to read data from serial port, which happens in blocking manner. Try it and tell if it worked.
On Antanas Veiverys blog you can find two possible ways to solve it.
(2012) By adjusting the mono source code.
http://antanas.veiverys.com/enabling-serialport-datareceived-event-in-mono/
(2013) By not touching the mono source but solving the issue in a derived class.
http://antanas.veiverys.com/mono-serialport-datareceived-event-workaround-using-a-derived-class/
(2014)
However, I encourage you to read Ben Voigts blog post where he ignores using the DataReceivedEvent and instead used the BaseStream async BeginRead/EndRead functions to read data from the serial port.
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport#comment-840
Implementing and using the given code sample works on both Windows/Unix, so I have tested. And it is more elegant than using the blocking Read() function in a threaded fashion.
mono does not support Event for serialport.
It is shown on mono's website
I have the same problem with SerialPort.DataReceived. Konrad's advice.
using System.IO.Ports;
using System.Threading;
namespace Serial2
{
class MainClass
{
public static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
Thread readThread = new Thread(new ThreadStart(ReadThread));
readThread.Start();
Thread.Sleep(200); // TODO: Ugly.
writeThread.Start();
Console.ReadLine();
}
private static void WriteThread()
{ // get port names with dmesg | grep -i tty
SerialPort sp2 = new SerialPort("/dev/ttyS5", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
if(sp2.IsOpen)
Console.WriteLine("WriteThread(), sp2 is open.");
else
Console.WriteLine("WriteThread(), sp2 is open.");
sp2.Write(" This string has been sent over an serial 0-modem cable.\n"); // \n Needed (buffering?).
sp2.Close();
}
private static void ReadThread()
{
SerialPort sp = new SerialPort("/dev/ttyS4", 115200, Parity.None, 8, StopBits.One);
sp.Open();
if(sp.IsOpen)
Console.WriteLine("ReadThread(), sp Opened.");
else
Console.WriteLine("ReadThread(), sp is not open.");
while(true)
{
Thread.Sleep(200);
if(sp.BytesToRead > 0)
{
Console.WriteLine(sp.ReadLine());
}
}
}
}
}