A thread should not start event the start method is called.. is it possible? in c#
As this code demonstrates, the thread automatically is created in a suspended state and will not start until you call start.
class Program
{
static void Main(string[] args)
{
Worker w = new Worker();
Console.ReadKey();
w.Start();
Console.ReadKey();
w.Stop();
Console.ReadKey();
}
}
class Worker
{
System.Threading.Thread workerThread;
bool work;
public Worker()
{
System.Threading.ThreadStart ts = new System.Threading.ThreadStart(DoWork);
workerThread = new System.Threading.Thread(ts);
}
public void Start()
{
work = true;
workerThread.Start();
}
public void Stop()
{
work = false;
}
private void DoWork()
{
while(work)
{
Console.WriteLine(System.DateTime.Now.ToLongTimeString());
System.Threading.Thread.Sleep(1000);
}
}
}
(This was created with C# on .NET 3.5, was threading different for 2.0?)
Related
I am learning Java and have encountered an unexpected problem:
variable i is getting updated in mouse listener but updated value is not getting passed back to main program. But if I uncomment Thread.sleep(1) block everything is back to normal.
Here is the program:
import java.awt.*;
import java.awt.event.*;
public class MouseEventDemo extends Frame
implements MouseListener {
String msg = "";
int mouseX = 0, mouseY = 0; // coordinates of mouse
static int i=0;//State variable
public MouseEventDemo()
{
addMouseListener(this);
addWindowListener(new MyWindowAdapter());
}
// Handle mouse clicked.
public void mouseClicked(MouseEvent me)
{
i=1;
msg = "Click received. i= "+i;
mouseX = me.getX();
mouseY = me.getY();
repaint();
}
public void mouseMoved(MouseEvent me)
{
}
public void mouseDragged(MouseEvent me)
{
}
public void mouseExited(MouseEvent me)
{
}
public void mouseEntered(MouseEvent me)
{
}
public void mouseReleased(MouseEvent me)
{
}
public void mousePressed(MouseEvent me)
{
}
// Display msg in the window at current X,Y location.
public void paint(Graphics g)
{
g.drawString(msg, mouseX, mouseY);
}
public static void main(String[] args)
{
MouseEventDemo appwin = new MouseEventDemo();
appwin.setSize(new Dimension(300, 300));
appwin.setTitle("MouseEventDemo");
appwin.setVisible(true);
while (true)
{
if(i==1)
{
System.out.println("Value of i is: "+i);
i=0;
}
/*
try
{
Thread.sleep(1);
}
catch(Exception e)
{
System.out.println(e);
};
*/
}
}
}
class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
}
This program behaves not like I have expected, but with Thread.sleep(1) it changes it behaviour
I am making use of Prism in my xamarin forms project.I was able to use dependency injection(constructor injection) in my View Model without any problems.I am also making use of background services to push long running tasks in the background.How do I inject dependency in my Background services?When I try to pass the interface object as a paramater to the constructor(SyncingBackgroundingCode) ,the object(SqliteService) is null.I have registered and resolved the objects in the dependency injection container.
How to handle this case?Can anybody provide an example or link to implement this scenario?
This is the piece of code where im trying to implement dependency injection.
This is in Droid :-
public class AndroidSyncBackgroundService : Service
{
CancellationTokenSource _cts;
public override IBinder OnBind (Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand (Intent intent, StartCommandFlags flags, int startId)
{
_cts = new CancellationTokenSource ();
Task.Run (() => {
try {
//INVOKE THE SHARED CODE
var oBackground = new SyncingBackgroundingCode();
oBackground.RunBackgroundingCode(_cts.Token).Wait();
}
catch (OperationCanceledException)
{
}
finally {
if (_cts.IsCancellationRequested)
{
var message = new CancelledTask();
Device.BeginInvokeOnMainThread (
() => MessagingCenter.Send(message, "CancelledTask")
);
}
}
}, _cts.Token);
return StartCommandResult.Sticky;
}
public override void OnDestroy ()
{
if (_cts != null) {
_cts.Token.ThrowIfCancellationRequested ();
_cts.Cancel ();
}
base.OnDestroy ();
}
}
This is in PCL:-
public class SyncingBackgroundingCode
{
public SQLiteConnection _sqlconnection;
SqliteCalls oSQLite = new SqliteCalls();
ISqliteService _SqliteService;
public SyncingBackgroundingCode(ISqliteService SqliteService)
{
//object is null
}
public async Task RunBackgroundingCode(CancellationToken token)
{
DependencyService.Get<ISQLite>().GetConnection();
await Task.Run (async () => {
token.ThrowIfCancellationRequested();
if (App.oSqliteCallsMainLH != null)
{
App.bRunningBackgroundTask = true;
oSQLite = App.oSqliteCallsMainLH;
await Task.Run(async () =>
{
await Task.Delay(1);
oSQLite.ftnSaveOnlineModeXMLFormat("Offline", 0);
oSQLite.SyncEmployeeTableData();
oSQLite.SaveOfflineAppCommentData();
oSQLite.SaveOfflineAdditionToFlowData();
await Task.Delay(500);
var msgStopSyncBackgroundingTask = new StopSyncBackgroundingTask();
MessagingCenter.Send(msgStopSyncBackgroundingTask, "StopSyncBackgroundingTask");
});
}
}, token);
}
}
Unfortunately Xamarin and Xamarin Forms don't give frameworks like Prism anywhere to tie into to handle IoC scenarios. There are a couple of ways you can handle this though.
First the Container is a public property on the PrismApplication in your background service you could do something like:
public class FooBackgroundService
{
private App _app => (App)Xamarin.Forms.Application.Current;
private void DoFoo()
{
var sqlite = _app.Container.Resolve<ISQLite>();
}
}
Another slightly more involved way would be to use the ServiceLocator pattern. You might have something like the following:
public static class Locator
{
private static Func<Type, object> _resolver;
public static T ResolveService<T>() =>
(T)_resolver?.Invoke(typeof(T));
public static void SetResolver(Func<Type, object> resolver) =>
_resolver = resolver;
}
In your app you would then simply set the resolver. Prism actually does something similar to this with the ViewModel locator, which then allows it to inject the correct instance of the NavigationService.
public class App : PrismApplication
{
protected override void OnInitialized()
{
SetServiceLocator();
NavigationService.NavigateAsync("MainPage");
}
protected override void RegisterTypes()
{
// RegisterTypes
}
private void SetServiceLocator()
{
Locator.SetResolver(type => Container.Resolve(type, true));
}
}
Finally your service would simply reference the Service Locator like:
public class BarBackgroundService
{
public void DoBar()
{
var sqlite = Locator.ResolveService<ISQLite>();
// do foo
}
}
I have written a TopShelf service / console app, which appears to be running as intended, except I would like it to run once on boot, then disable itself until the next boot/reboot.
I was hoping this would work:
class MyServiceClass
{
public void Start()
{
// do the things that need doing
this.Stop();
}
public void Stop()
{
}
But that doesn't work, presumably because the this.Stop() command is there for cleanup, not for causing the service to stop.
My Program.cs looks like this:
// Uses Topshelf: http://topshelf-project.com/
// Guided by: http://www.ordina.nl/nl-nl/blogs/2013/maart/building-windows-services-with-c-and-topshelf/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Topshelf;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted(myServiceClass => myServiceClass.Start());
serviceConfigurator.WhenStopped(myServiceClass => myServiceClass.Stop());
});
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
}
How do I go about stopping the service at the end of execution?
UPDATE: Based on Damien's input, I now have:
public class MyServiceClass
{
private readonly Task task;
private HostControl hostControl;
public MyServiceClass()
{
task = new Task(DoWork);
}
private void DoWork()
{
Console.WriteLine("Listen very carefully, I shall say this only once");
hostControl.Stop();
}
public void Start(HostControl hostControl)
{
// so we can stop the service at the end of the check
this.hostControl = hostControl;
// start the DoWork thread
task.Start();
}
public void Stop()
{
}
};
and an updated Program.cs
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>((serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted((myServiceClass, hostControl) => myServiceClass.Start(hostControl));
serviceConfigurator.WhenStopped(myServiceClass => myServiceClass.Stop());
}); /* compiler thinks there's a ")" missing from this line */
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
However, this will not compile. My compiler suggests that a ")" is missing on (or around) my comment (shown in the code above), but any addition of a close parenthesis just adds to the error list.
I feel like I'm close... any ideas?
Got this working eventually:
public class MyServiceClass : ServiceControl
{
private readonly Task task;
private HostControl hostControl;
public MyServiceClass()
{
task = new Task(DoWork);
}
private void DoWork()
{
Console.WriteLine("Listen very carefully, I shall say this only once");
//hostControl.Stop();
}
public bool Start(HostControl hostControl)
{
// so we can stop the service at the end of the check
this.hostControl = hostControl;
// start the DoWork thread
task.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
return true;
}
};
and
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted((myServiceClass, hostControl) => myServiceClass.Start(hostControl));
serviceConfigurator.WhenStopped((myServiceClass, hostControl) => myServiceClass.Stop(hostControl));
});
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
My 2nd attempt had a spare "(" at the first mention of serviceConfigurator, then I needed to turn my void Start and Stop functions into bool functions. Hope this helps someone.
Following is the code which is showing the above exception on debugging :
Firstly I am trying to call a class HTTPConnection from the below menu item.
protected MenuItem _SelectDealerItem = new MenuItem("Select Dealer",100,10)
{
public void run()
{
new HTTPConnection();
}
};
In HTTPConnection Class I am checking the connection type and calling another Class TSelectDealerScreen:
public class HTTPConnection {
ConnectionFactory _factory = new ConnectionFactory();
public HTTPConnection()
{
int[] _intTransports = {
TransportInfo.TRANSPORT_TCP_WIFI,
TransportInfo.TRANSPORT_WAP2,
TransportInfo.TRANSPORT_TCP_CELLULAR
};
for(int i=0;i<_intTransports.length;i++)
{
int transport = _intTransports[i];
if(!TransportInfo.isTransportTypeAvailable(transport)||!TransportInfo.hasSufficientCoverage(transport))
{
Arrays.removeAt(_intTransports,i);
}
}
TcpCellularOptions tcpOptions = new TcpCellularOptions();
if(!TcpCellularOptions.isDefaultAPNSet())
{
tcpOptions.setApn("My APN");
tcpOptions.setTunnelAuthUsername("user");
tcpOptions.setTunnelAuthPassword("password");
}
if(_intTransports.length>0)
{
_factory.setPreferredTransportTypes(_intTransports);
}
_factory.setTransportTypeOptions(TransportInfo.TRANSPORT_TCP_CELLULAR, tcpOptions);
_factory.setAttemptsLimit(5);
Thread t = new Thread(new Runnable()
{
public void run()
{
ConnectionDescriptor cd = _factory.getConnection("http://excellentrealtors.info/Smart-Trace/get_dealer.php");
if(cd!=null)
{
Connection c = cd.getConnection();
displayContent(c);
}
}
});
t.start();
}
private void displayContent(final Connection conn)
{
UiApplication.getUiApplication().pushScreen(new TSelectDealerScreen(conn));
}
}
In TSelectDealerScreen class i am simply trying to read the stream, but it is showing illegal state exception whenever i try to debug, I am not much familiar to blackberry programming, kindly advice.
public class TSelectDealerScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();
public TSelectDealerScreen(Connection conn)
{
_rtfOutput.setText("Retrieving Data.Please Wait");
add(_rtfOutput);
ContentReaderThread t = new ContentReaderThread(conn);
t.start();
}
private final class ContentReaderThread extends Thread {
private Connection _connection;
ContentReaderThread(Connection conn)
{
_connection = conn;
}
public void run()
{
String result = "";
OutputStream os = null;
InputStream is = null;
try
{
OutputConnection outputConn = (OutputConnection)_connection;
os = outputConn.openOutputStream();
String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n";
os.write(getCommand.getBytes());
os.flush();
// Get InputConnection and read the server's response
InputConnection inputConn = (InputConnection) _connection;
is = inputConn.openInputStream();
byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
result = new String(data, "US-ASCII");
// is.close();
System.out.print(result);
}
catch(Exception e)
{
result = "ERROR fetching content: " + e.toString();
}
finally
{
// Close OutputStream
if(os != null)
{
try
{
os.close();
}
catch(IOException e)
{
}
}
// Close InputStream
if(is != null)
{
try
{
is.close();
}
catch(IOException e)
{
}
}
// Close Connection
try
{
_connection.close();
}
catch(IOException ioe)
{
}
}
// Show the response received from the web server, or an error message
showContents(result);
}
}
public void showContents(final String result)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
_rtfOutput.setText(result);
}
});
}
}
In your HTTPConnection class, you do:
Thread t = new Thread(new Runnable()
{
public void run()
{
ConnectionDescriptor cd = _factory.getConnection("http://excellentrealtors.info/Smart-Trace/get_dealer.php");
if(cd!=null)
{
Connection c = cd.getConnection();
displayContent(c);
}
}
});
t.start();
That runs everything inside run() on a background thread. But, inside displayContent(c), you do:
UiApplication.getUiApplication().pushScreen(new TSelectDealerScreen(conn));
which is a UI operation.
Trying to modify the UI from a background thread normally causes an IllegalStateException.
I believe you just need to wrap the call to pushScreen() with this:
private void displayContent(final Connection conn) {
final UiApplication app = UiApplication.getUiApplication();
app.invokeLater(new Runnable() {
public void run() {
// this code is run on the UI thread
app.pushScreen(new TSelectDealerScreen(conn));
}
});
}
Also, if you're an Android developer, and you want help doing normal background/UI thread stuff, you might check out this other answer I wrote on "porting" AsyncTask to BlackBerry Java
I am trying to use ninject with db4o and I have a problem. This is the relevant code from the Global.aspx
static IObjectServer _server;
protected override void OnApplicationStarted()
{
AutoMapperConfiguration.Configure();
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
if (_server == null)
{
// opening a server for a client/server session
IServerConfiguration serverConfiguration = Db4oClientServer.NewServerConfiguration();
serverConfiguration.File.Storage = new MemoryStorage();
_server = Db4oClientServer.OpenServer(serverConfiguration, "myServerDb.db4o", 0);
}
}
public static IObjectContainer OpenClient()
{
return _server.OpenClient();
}
public MvcApplication()
{
this.EndRequest += MvcApplication_EndRequest;
}
private void MvcApplication_EndRequest(object sender, System.EventArgs e)
{
if (Context.Items.Contains(ServiceModule.SESSION_KEY))
{
IObjectContainer Session = (IObjectContainer)Context.Items[ServiceModule.SESSION_KEY];
Session.Close();
Session.Dispose();
Context.Items[ServiceModule.SESSION_KEY] = null;
}
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
public override void OnApplicationEnded()
{
_server.Close();
}
and this is the code in ServiceModule
internal const string SESSION_KEY = "Db4o.IObjectServer";
public override void Load()
{
Bind<IObjectContainer>().ToMethod(x => GetRequestObjectContainer(x)).InRequestScope();
Bind<ISession>().To<Db4oSession>();
}
private IObjectContainer GetRequestObjectContainer(IContext Ctx)
{
IDictionary Dict = HttpContext.Current.Items;
IObjectContainer container;
if (!Dict.Contains(SESSION_KEY))
{
container = MvcApplication.OpenClient();
Dict.Add(SESSION_KEY, container);
}
else
{
container = (IObjectContainer)Dict[SESSION_KEY];
}
return container;
}
I then try to inject it into my session as such:
public Db4oSession(IObjectContainer client)
{
db = client;
}
however, after the first call, the client is always closed - as it should be because of the code in MvcApplication_EndRequest. The problem is that the code in GetRequestObjectContainer is only ever called once. What am I doing wrong?
Also, MvcApplication_EndRequest is always called 3 times, is this normal?
Thanks!
This seems to have done the trick... add InRequestScope to the other injection:
Bind<ISession>().To<Db4oSession>().InRequestScope();