how to use a separate STA thread to call clipboard from timer in console application? - multithreading

I am struggling with using Clipboard from a console application. The error handler would return the following error.
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made"
I set the STA attribute to the main function and that worked well when calling from main. However, I need to cyclically call that function and in this case I get back that error.
I'm trying to figure out how to use an own thread in my funtion. Now, it just works once but in the 2nd call from my timer, I am not able to reach the area of the code after where I created the thread
public string getRawData()
{
string sChatRawTxt = string.Empty;
try
{
// copy data to clipboard using an Autoit script
Process.Start("copyChatToClipboard.au3");
System.Threading.Thread.Sleep(500);
Thread staThread = new Thread(x =>
{
if (Clipboard.ContainsText())
{
sChatRawTxt = Clipboard.GetText();
Clipboard.Clear();
}
});
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return sChatRawTxt;
}
This is the timer from where my function is called. If I set a breakpoint to separateComments, it only works one time, then I am no longer able to reach that position. Do I have to somehow close the thread from before?
public void OnTimedEvent_scannerCyclic(object source, ElapsedEventArgs e)
{
string sRawTxt = getRawData();
// then separate/ remove the useless data
string sComments = SeparateComments(sRawTxt);
}
[STAThread]
public static void Main(string[] args)
{
stdTimer = new System.Timers.Timer(1000);
stdTimer.Elapsed += new ElapsedEventHandler(this.OnTimedEvent_scannerCyclic);
stdTimer.Enabled = true;
while (true)
{
// main program
//System.Threading.Thread.Sleep(1000);
}
}
thanks a lot for help
So the only solution i figured was to use my own timer that i implemented in the main as below
TimeSpan deltaT = TimeSpan.FromMilliseconds(1000);
DateTime timeLastCall = DateTime.Now;
while (true)
{
// main program
DateTime currentTime = DateTime.Now;
if(currentTime - timeLastCall > deltaT)
{
Scanner.mainCyclicCall();
timeLastCall = currentTime;
}
System.Threading.Thread.Sleep(100);
}
I dont have a lot of c# experience, it is actually my first little project. I dont know if there is a better way to cyclically access Clipboard in a console application. Also using a dispatcher timer did not work out, I read console apps dont have a dispather.

Related

Do I need to use thread and a task in JavaFX to run something in background when a thread will do the job?

I'm using a thread to periodically run a three second background animation.
I adapted the code in question from a Thread Demo example written in Swing and used
it to replace a not quite working earlier version that used both a thread and a task.
My program stops/suspends the thread when either playing a video or running an animation
and starts a new thread when ending the video or animation. This seems to work without
any downside which is why I'm puzzled why my earlier JavaFX searches hadn't turned up
a similar solution to the one I'm using. It seems a rather direct approach for running
short, simple background animations.
Where am I going wrong with this? What am I missing? How would I rewrite this code
using both a Thread and a Task or do I need to?
I should add - the while and run statements are virtually unchanged from the original
and the only significant addition to the Swing code was to add thread.setDaemon( true )
to startThread().
A podcast listener.
// background thread
class BackGround extends Thread {
#Override
public void run() {
while ( suspend.getValue() == false ) {
try {
int r = shared.randInt( 5, 10 );
Thread.sleep( r * 1000 );
} catch ( InterruptedException e ) {
// do nothing
}
if ( suspend.getValue() == false ) {
Platform.runLater( () -> {
int g = shared.cssGradients.length - 1;
g = shared.randInt( 0, g );
gradientColor.set( shared.cssGradients[g] );
Boolean bif = shared.updatePanes( shared.cssGradients[g],
leftPane, rightPane );
});
}
}
}
} // class background
// start thread
public synchronized void startThread() {
thread = new BackGround(); // Thread thread ...defined elsewhere
thread.setDaemon( true );
thread.start();
}
// stop thread
public synchronized void stopThread() {
suspend.set( true );
}
The reason the Task class is useful for JavaFX is that it provides a number of callbacks like succeeded(), failed() or cancelled() and methods like updateProgress() and updateMessage() that will run in the JavaFX Application thread and therefore let you update the UI without Platform.runLater( () -> { ... }); This makes the Task class a perfect choice for doing background tasks like downloading data or long running computations.
However, since your thread simply runs continuously without ever really finishing its work, it doesn't seem that you would need any of the additional functionality a Task would provide you with over a simple Thread.
Still, if you really wanted to convert your code to use a Task, it would look just like this:
class BackGround extends Task<Void> {
#Override
protected Void call() throws Exception {
while (suspend.getValue() == false) {
try {
int r = shared.randInt(5, 10);
Thread.sleep(r * 1000);
} catch (InterruptedException e) {
// do nothing
}
if (suspend.getValue() == false) {
Platform.runLater(() -> {
int g = shared.cssGradients.length - 1;
g = shared.randInt(0, g);
gradientColor.set(shared.cssGradients[g]);
Boolean bif = shared.updatePanes(shared.cssGradients[g],
leftPane, rightPane);
});
}
}
return null;
}
}
// start thread
public synchronized void startThread() {
Task<Void> bg = new BackGround();
Thread taskThread = new Thread(bg);
taskThread.setDaemon(true);
taskThread.start();
}
// stop thread
public synchronized void stopThread() {
suspend.set( true );
}
As you see, it really doesn't make a difference for you, as you don't need anything that a Thread couldn't give you. If however you wanted to have closer communication with the UI thread, e.g. showing a progress bar or showing status updates, then a Task would give you the tools to do that.
I guess its also worth mentioning that the use of a Timeline would be quite elegant for triggering your animations. It would look somewhat like this:
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
int g = shared.cssGradients.length - 1;
g = shared.randInt(0, g);
gradientColor.set(shared.cssGradients[g]);
Boolean bif = shared.updatePanes(shared.cssGradients[g], leftPane, rightPane);
}
}
));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
The code inside the handle() method is run every second in the JavaFX Application thread. Unfortunately this only lets you set a fixed time between executions, while you seem to want to wait a random amount of time each time.
TL;DR: Using a Thread is ok, because you don't need the additional functionalities of a Task in your use case.

WinForms Thread-safe Controls

I spend a lot of time working with Windows Forms controls but from a background worker thread - I suppose this is good practice really since you don't want your form to be locking up when people click buttons. To be honest, with just about everything GUI related action I normally do in a background worker thread, so the interface is nice an responsive to the user (Wish more people would do that!).
So my question is... every time I have to interact with controls I have to "Invoke" them, with something like:
if (control.InvokeRequired)
{
//
}
Standard practice right? However, this leads me to some terribly messy code, because just about every control type I have, I need a MethodInvoker delegate or something. It's adding thousands of lines of code to my protects, and its terribly time consuming.
I currently have hundreds of "property setting" methods like:
private void Safe_SetLableText(Label control, string text)
{
if (control.InvokeRequired)
{
control.Invoke((MethodInvoker)delegate
{
control.Text = text;
});
}
else
{
control.Text = text;
}
}
So, is there some other technique, or way to do this, or some way to being able to always alter a property of a control, no matter what the control is and no matter what thread im in?
something like: (pseudocode)
BackgroundWorker.RunWorkerAsync();
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
InvokeAnyControls();
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
RestoreAnyControls();
}
You could wrap your InvokeRequired code with a delegate, like so:
public static void Invoke2<TControl>(this TControl c, Action<TControl> code) where TControl : Control {
if( c.InvokeRequired ) c.Invoke( delegate() { code(c); } );
else code(c);
}
Then use it like so:
private void Safe_SetLableText(Label control, string text) {
control.Invoke2( c => c.Text = text );
}
Of course you might want better names than Invoke2, but I hope the idea sits will with you. Note that the lambda-expression syntax is a C# 3.0 feature, but the Action<T> delegate is part of .NET 2.0, so this will compile against the .NET Framework 2.0 so long as you're VS2008 or later.
I'm posting an answer to my own question because I think it will add value to the community.
1) I wanted to "simplify" my code, and one if the most important finds was that that the:
control.InvokeRequired
really isnt needed... its pretty much a given. Importantly, you CAN rely on the fact that the control will need to be invoked if you are in a background (or non-UI) thread.
2) The invocation travels "UP" the control tree, so if you have:
Form > Control > Control inside Control > etc > etc
You only need to invoke "Form" (top most), and then you can alter the properties of the child elements.
So here is my clean and simple solution to working with background workers (or non-UI threads). I have just tested this now and it works great.
public partial class Form1: Form
{
public Form1()
{
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(this.bgDoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgComplete);
bgw.RunWorkerAsync();
}
private void bgComplete(object sender, EventArgs e)
{
// You are not in the UI thread now, so you can Invoke without error
this.Invoke((MethodInvoker)delegate
{
// Now you can change any property an any control within this form.
// Remember "this" refers to Form1.
this.label1.Text = "test123";
this.label2.Text = "test456";
this.label3.Text = this.label4.Text;
// You can set progress bars too, not just label text
}
}
private void bgDoWork(object sender, DoWorkEventArgs e)
{
// Do something that takes a long time
}
}
As you are already using the Background worker why don't you 'misuse' OnProgressChanged?
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(1, "state");
DoSomeMoreDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(2, YourObjectHere);
}
void OnProgressChanged(ProgressChangedEventArgs progressArgs)
{
switch(progressArgs.ProgressPercentage)
{
case 1:
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
break;
case 2:
// other stuff
YourObject obj = (YourObject) progressArgs.UserState;
// wahtever...
break;
default:
break;
}
}

Seeking C# threading clarification

I'm new to threading; in fact I'm not even trying to multi- thread the Windows Forms app I'm working on, but all of my searches on this issue lead me to the topic of multithreading. When debugging in Visual Studio 2010 Express, it seems to "jump around" to use the term I've seen others use to describe the same problem. When I let it run, sometimes it runs as expected, other times it just seems to keep running, getting hung up.
In trying to hone my question, I think I need to figure out:
If the timer class calls a method on a different thread, and there isn't an obvious danger of unpredictable instance values/ state corruption in the executing code (there aren't any conditional checks of instance variables etc), why would that method called by the timer appear to behave unpredictably? To me it seems that the code should run synchronously, and if a different thread is used for part of the process, so be it. I can't see where there is opportunity for thread corruption.
When the program starts, it prompts for the timer to be set to run a data download process. After the procedure runs, the timer is set again to a default time, at the end of the procedure. Consistently, the initial timer setting works, and fires as expected, running the data download process... it's that data download method, somewhere within it it goes awry. The last line of code is what sets the timer again, but I can't tell if it's getting hit while debugging it. (jumping around)..
I've added relevant code below... and I stepped into every procedure in my code from the beginning... they all show current thread id 10. This is up to an including the timer firing off, and stopping at a breakpoint at the very next line to execute, which is the data download process. The current thread at that point: 14. I've built the solution before running it/ trying to debug btw. Any ideas?
public partial class frmTradingAppMain : Form
{
private TradingAppDataRunManager drm;
private void frmTradingAppMain_Shown(object sender, EventArgs e)
{
drm = new TradingAppDataRunManager();
drm.StatusChanged += new DataRunManager.DRMStatusChangeHandler(UpdateFormData);
drm.InitializeOrScheduleDataRun();
}
private void UpdateFormData()
{
this.Invoke(new DataRunManager.DRMStatusChangeHandler(UpdateFormDataImpl));
}
private void UpdateFormDataImpl()
{
lblDataDwnLoadManagerStatus.Text = Convert.ToString(drm.Status);
if (drm.Status == DataRunManager.DRMStatus.Inactive)
{
lblNextScheduledDataDownloadDate.Text = "Date not set.";
lblNextScheduledDataDownloadTime.Text = "Time not set.";
}
else
{
lblNextScheduledDataDownloadDate.Text = drm.DateTimeOfNextScheduledDataRun.ToShortDateString();
lblNextScheduledDataDownloadTime.Text = drm.DateTimeOfNextScheduledDataRun.ToShortTimeString();
}
}
}
public abstract class DataRunManager
{
protected DataRunTimer dataRuntimer;
public delegate void DRMStatusChangeHandler();
public event DRMStatusChangeHandler StatusChanged;
public DRMStatusChangeHandler statusChanged;
public void InitializeOrScheduleDataRun()
{
if (DataRunIsAvailable() && UserWouldLikeToPerformDataRun())
RunMainDataProcedure(null);
else
ScheduleDataRun();
}
public void RunMainDataProcedure(object state)
{
start = DateTime.Now;
Status = DRMStatus.Running;
StatusChanged();
GetDataCollections();
foreach (DataCollection dcl in dataCollectionList)
{
dcl.RunDataCollection();
dcl.WriteCollectionToDatabase();
}
PerformDBServerSideProcs();
stop = DateTime.Now;
WriteDataRunStartStopTimesToDB(start, stop);
SetDataRunTimer(DateTimeOfNextAvailableDR());
}
public void ScheduleDataRun()
{
FrmSetTimer frmSetTimer = new FrmSetTimer(DateTimeOfNextAvailableDataRun);
DateTime currentScheduledTimeOfNextDataRun = DateTimeOfNextScheduledDataRun;
DRMStatus currentStatus= Status;
try
{
frmSetTimer.ShowDialog();
DateTimeOfNextScheduledDataRun = (DateTime)frmSetTimer.Tag;
SetDataRunTimer(DateTimeOfNextScheduledDataRun);
}
catch
{
Status = currentStatus;
DateTimeOfNextScheduledDataRun = currentScheduledTimeOfNextDataRun;
}
}
}
public class DataRunTimer
{
System.Threading.Timer timer;
public DataRunTimer(){}
public void SetNextDataRunTime(TimerCallback timerCallback, DateTime timeToSet)
{
if (timer == null)
timer = new System.Threading.Timer(timerCallback);
TimeSpan delayTime = new TimeSpan(timeToSet.Day - DateTime.Now.Day, timeToSet.Hour - DateTime.Now.Hour, timeToSet.Minute - DateTime.Now.Minute,
timeToSet.Second - DateTime.Now.Second);
TimeSpan intervalTime = new TimeSpan(0, 0, 10);
timer.Change(delayTime, intervalTime);
}
public void DataRunTimerCancel()
{
if (timer != null)
timer.Dispose();
}
}

Working with threads in blackberry

I am using threads in blackberry to perform web service calls. I want to get notified as soon as the call gets a response back. I was using
Handlers
in android. I didnt find anything similar in blackberry.
Here is the code I am using to run the thread
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
How can I get a notification after the thread finished running?
How can I do this in blackberry?
Thanks
Added more Information : Thanks for your reply. Its really
informative. Let me explain a bit more on my issue. I have a
webservice call which is running on a thread. As soon as I get the
reply back from server I want to execute the next function(next call
to server) which is based on the response from the previous call.So I need to wait until I get a response back. Also
at them same time I need to show a activity indicator on screen. I was
using handler for this in android. I am looking for something similar
on blackberry.
So your question essentially is this
One thread does the job while the other thread waits for completion
The first thread completes the job and "notifies" the second thread.
This is a simple producer consumer problem. Here is the code how you can solve this.
class JobResult
{
boolean done = false;
}
JobResult result = new JobResult();
class Worker extends Thread
{
JobResult _result;
public Worker( JobResult result )
{
_result = result
}
public void run()
{
// Do some very long job
synchronized( _result )
{
// modify result
_result.done = true;
_result.notify();
}
}
}
public class Waiter extends Thread
{
JobResult _result;
public Waiter( JobResult result )
{
_result = result;
}
public void run()
{
synchroinzed( _result ){
while(! _result.done)
{
this.wait();
}
}
// Wait is over. You can do something now.
}
}
As I got the Zach's question - he asks how to execute some code that involves UI changes (something like showing an info popup or closing the progress popup) upon a background thread completion. On Android a Handler created on the UI thread is often used for that purpose.
In BB you can use another way which is similar to Swing on desktop Java. When you need some code to be executed on the UI thread you wrap it in a Runnable and pass to one of the following methods:
// Puts runnable object into this application's event queue,
// and waits until it is processed.
Application.invokeAndWait(Runnable runnable)
// Puts runnable object into this application's event queue.
Application.invokeLater(Runnable runnable)
// Puts runnable object into this application's event queue
// for repeated execution.
Application.invokeLater(Runnable runnable, long time, boolean repeat)
So the behaviour of the above calls is similar to what Handler.post(Runnable r) (and the like) does.
Note, you can always get a handle to your Application instance by a static call Application.getApplication().
So in the end of a background thread it is safe to do something like this:
Application.getApplication().invokeLater(new Runnable() {
public void run() {
progressScreen.close();
Dialog.alert("I am finished!");
}
});
It is similar to Android's:
handler.post(new Runnable() {
public void run() {
progressScreen.dismiss();
showDialog(DIALOG_TASK_FINISHED_ID);
}
});
Android has a much rich multi threading primitives. But you can achieve the same even in Blackberry with equal elegance. The solution I provide below is essentially the same as previous, but with a minor change. Waiter thread can be replaced with built-in utility to perform painting on UI thread using UiApplicaiton's invokeLater method. You don't actually need to "notify" anyone but just update the UI once a particular task is completed. Check the docs for more info.
Anyway, you can model your code along the lines:
class ProgressScreen extends FullScreen
{
LabelField _label;
public void start()
{
}
public void setMessage( final String message )
{
UiApplication.getApplication(
UiApplication.invokeLater(
new Runnable() {
_label.setText( message );
}
)
);
}
public void dismiss()
{
this.close();
}
}
interface WebserviceTask
{
int STATUS_CONDITIONS_NOT_SATISFIED = -3;
int STATUS_NET_ERR = -2;
int STATUS_FAILURE = -1;
int STATUS_SUCCESS = 0;
public int invoke();
}
public class Updater extends Thread
{
final int NUM_TASKS = 10;
WebServiceTask tasks[] = new WebServiceTask[ NUM_TASKS ];
WebServiceTask tasks[0] = new WebServiceTask(){
public int invoke()
{
int retCode = 0;
// invoke a particular web service
return STATUS_SUCCESS;
}
}
public void run()
{
ProgressScreen progress = new ProgressScreen();
progress.start();
for( int i=0; i < NUM_TASKS; i++ )
{
int retcode;
WebServiceTask t = tasks[i];
retcode = t.invoke();
String mesg;
switch( retcode )
{
case STATUS_SUCCESS: { mesg ="Task successfully completed!";} break;
case STATUS_NET_ERR: { mesg ="Could not connect to network";} break;
}
progress.setMessage(message);
}
progress.dismiss();
}
}
Note that I have provided only the stubs to give you an idea how you may accomplish. Let us know how it goes.

Silverlight - limit application to one WCF call at a time

Silverlight can only send a certain number of simultaneous WCF requests at a time. I am trying to serialize the requests that a particular section of my application is performing because I don't need them to run concurrently.
The problem is as follows (summary below):
"WCF proxies in Silverlight applications use the SynchronizationContext of the thread from which the web service call is initiated to schedule the invocation of the async event handler when the response is received. When the web service call is initiated from the UI thread of a Silverlight application, the async event handler code will also execute on the UI thread."
http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html
summary: basically, if you block the thread that is calling the async method, it will never get called.
I can't figure out the right model of threading this such which would give me what I want in a reasonable way.
My only other requirement is that I don't want the UI thread to block.
As far as I can see, what should work is if the UI thread has a worker thread which queues up the calls as Action delegates, then uses an AutoResetEvent to execute a task one at a time in yet another worker thread. There are two problems:
1) The thread that calls async can't block, because then async will never get called. In fact, if you put that thread into a wait loop, I've noticed it doesn't get called either
2) You need a way to signal from the completed method of the async call that it is done.
Sorry that was so long, thanks for reading. Any ideas?
I have used a class that i build on my own to execute load operations synchronous. With the class you can register multiple load operations of diffrent domaincontexts and then execute them one by one. You can provide an Action to the constructor of the class that gets called, when all operations are finished (successful or failed).
Here´s the code of the class. I think it´s not complete and you have to change it to match your expectations. Maybe it can help you in your situation.
public class DomainContextQueryLoader {
private List<LoadOperation> _failedOperations;
private Action<DomainContextQueryLoader> _completeAction;
private List<QueuedQuery> _pendingQueries = new List<QueuedQuery>();
public DomainContextQueryLoader(Action<DomainContextQueryLoader> completeAction) {
if (completeAction == null) {
throw new ArgumentNullException("completeAction", "completeAction is null.");
}
this._completeAction = completeAction;
}
/// <summary>
/// Expose the count of failed operations
/// </summary>
public int FailedOperationCount {
get {
if (_failedOperations == null) {
return 0;
}
return _failedOperations.Count;
}
}
/// <summary>
/// Expose an enumerator for all of the failed operations
/// </summary>
public IList<LoadOperation> FailedOperations {
get {
if (_failedOperations == null) {
_failedOperations = new List<LoadOperation>();
}
return _failedOperations;
}
}
public IEnumerable<QueuedQuery> QueuedQueries {
get {
return _pendingQueries;
}
}
public bool IsExecuting {
get;
private set;
}
public void EnqueueQuery<T>(DomainContext context, EntityQuery<T> query) where T : Entity {
if (IsExecuting) {
throw new InvalidOperationException("Query cannot be queued, cause execution of queries is in progress");
}
var loadBatch = new QueuedQuery() {
Callback = null,
Context = context,
Query = query,
LoadOption = LoadBehavior.KeepCurrent,
UserState = null
};
_pendingQueries.Add(loadBatch);
}
public void ExecuteQueries() {
if (IsExecuting) {
throw new InvalidOperationException("Executing of queries is in progress");
}
if (_pendingQueries.Count == 0) {
throw new InvalidOperationException("No queries are queued to execute");
}
IsExecuting = true;
var query = DequeueQuery();
ExecuteQuery(query);
}
private void ExecuteQuery(QueuedQuery query) {
System.Diagnostics.Debug.WriteLine("Load data {0}", query.Query.EntityType);
var loadOperation = query.Load();
loadOperation.Completed += new EventHandler(OnOperationCompleted);
}
private QueuedQuery DequeueQuery() {
var query = _pendingQueries[0];
_pendingQueries.RemoveAt(0);
return query;
}
private void OnOperationCompleted(object sender, EventArgs e) {
LoadOperation loadOperation = sender as LoadOperation;
loadOperation.Completed -= new EventHandler(OnOperationCompleted);
if (loadOperation.HasError) {
FailedOperations.Add(loadOperation);
}
if (_pendingQueries.Count > 0) {
var query = DequeueQuery();
ExecuteQuery(query);
}
else {
IsExecuting = false;
System.Diagnostics.Debug.WriteLine("All data loaded");
if (_completeAction != null) {
_completeAction(this);
_completeAction = null;
}
}
}
}
Update:
I´ve just noticed that you are not using WCF RIA Services, so maybe this class will not help your.
There are some options:
- You can take a look at the Agatha-rrsl either by inspecting the implementation of it or by just using it instead of pure wcf. The framework allows you to queue requests. You can read more here.
- Another option is to use the Reactive extension. There is a SO example here and more info here and here.
- You can try the Power Thread library from Jeffrey Richter. He describes it on his book CLR via C#. You can find the library here. This webcast gives you some info about it.
- You can always roll your own implementation. The yield statement is a good help here. Error handling makes it very difficult to get the solution right.

Resources