okay, so here is what im doing:
class Connection
{
public int SERVERID;
private Thread connection;
public Connection()
{
connection = new Thread(new ThreadStart(this.Run));
}
public void Start(int serverid)
{
SERVERID = serverid;
connection.Start();
}
void Run()
{
while(true)
{
//do stuff here
}
}
}
now, there is the class i need to manage, here is how im calling it:
static void Main(string[] args)
{
StartConnection(1);
StartConnection(2);
StartConnection(3);
//etc
}
static void StartCOnnection(int serverid)
{
Connection connect = new Connection();
connect.Start(serverid);
}
i was origanally trying to do somthing like this:
foreach(Connection connect in Connection)
{
if(connect.SERVERID == 2)
{
//destroy the thread, and class.
}
}
but that gets the error " 'Connection' is a 'type' but is used like a 'variable'
", and i dont know how to do that destroy the thread and class part...
Summary:
So what i basically need to do, is get a list of all the open Connetion class's, and be able to, based on the settings of the class be able to destroy it. how do i do this?
~code examples please
You didn't say what kind of errors you're getting. That might help. Also; you might want to add a stop method on your connection that looks like:
public void Stop()
{
if (this.connection.IsAlive)
{
this.stopCondition = true;
this.connection.Join();
}
}
where stopCondition is a class member that is checked in your while loop (instead of just 'true').
The code in you Main() won't compile.
You need something like:
List<Connection> connections = new List<Connection> ();
Connection connect;
connect = new Connection();
connect.Start(1);
connections.Add(connect);
connect = new Connection();
connect.Start(2);
connections.Add(connect);
// etc
And then you can later do:
foreach(Connection connect in connections)
{
if(connect.SERVERID == 2)
{
//destroy the thread, and class.
}
}
For the actual stopping, I agree with SnOrfus' answer. You need to build in some logic to break the while-loop.
Related
I'm working on a class that looks like this:
public class MatchmakingService {
private bool working;
private List<MatchmakingUser> matchmakingUsers;
// ...
public MatchmakingService()
{
matchmakingUsers = new List<MatchmakingUser>();
}
public void StartService () {
var thread = new Thread(this.MatchmakingWork);
working = true;
thread.Start();
}
void MatchmakingWork () {
while (working)
{
// some work
Thread.Sleep(1000);
}
}
// ...
public void AddMatchmakingUser(MatchmakingUser user)
{
matchmakingUsers.Add(user);
}
}
Now I'm worried about matchmakingUsers list so I figured I'd just call this AddMatchmakingUser to execute in this service thread, but don't really know how to. I've read about Dispatcher class but either mono in Unity doesn't have it or it's a different technology entirely. Basically I'd like to do:
MatchmakingService mmService = new MatchmakingService();
mmService.Start();
// sometime later when needed
mmService.Somehowinvokeinworkingthread(mmService.AddMatchMakingUser(...));
Just call AddMatchmakingUser from any thread and synchronize all the code that's accesing the list to prevent them from occuring at the same time and causing a race condition:
public void AddMatchmakingUser(MatchmakingUser user)
{
lock (matchmakingUsers)
{
matchmakingUsers.Add(user);
}
}
Do the same inside MatchmakingWork whenever you are accessing the list.
My Goal: I have HASP with whom I need to communicate using Serial port.
The thing is many functions from different threads may want to communicate to this HASP - and I want some synchronization to occur.
What I did: I created wrapper class called HASPClass. Looks like this:
class HASPCLass
{
SerialPort m_port;
HASPClass(..)
{
//.. Init some other properties
m_port.Open();
//..
}
void CustomWriteToHASP()
{
//.. Do something
m_port.Write(...);
}
void CustomReadHASP()
{
//.. Do something
m_port.Read(...);
}
void Close ()
{
//Some code to close m_port
};
}
Usage of this class would be:
Function1 from some thread:
HASPClass o = new HASPClass(..);
o.CustomWriteToHASP(..)
Function2 from other thread:
HASPClass o1 = new HASPClass(..);
o1.CustomReadHASP(..)
Problem1: Now if o didn't close the m_port - constructor of o1 will throw since port is open.
I want to avoid this and make o1 wait for o to finish job.
What I thought: Maybe I should make m_port static - and put static lock everywhere it is used in HASPClass, will it solve above problem? Also the constructor will be changed to only open static m_port if it is closed. Will this approach solve most of the problems I outlined before?
Update: My other problem is that different objects might specify different parameters (baud rate etc.) in constructor - so I encounter a problem :( since I have single static m_port. :(. What to do in such case?? (I could relax this requirement and say all objects will put same parameters in constructor, but will it help?)
A simple singleton pattern might look something like this:
class HASPClass
{
private static HASPClass _instance;
private HASPClass(..)
{
//.. Init some other properties
}
public static GetInstance(...)
{
// Note, if called with different parameters then this will be
// quite a bit more complicated
if (_instance == null)
{
_instance = new HASPClass(...)
}
return _instance;
}
}
Now when you call it, you'd do something like:
HASPClass o = HASPClass.GetInstance(..);
o.CustomWriteToHASP(..)
But...since you are multithreading, this pattern won't be safe. You'll need to implement some locking around the critical GetInstance section to ensure that you don't create more than one object. So you could do something like:
private static object lockObj = new object();
public static GetInstance(...)
{
// Note, if called with different parameters then this will be
// quite a bit more complicated
if (_instance == null)
{
lock (lockObj)
{
if (_instance == null)
{
_instance = new HASPClass(...)
}
}
}
return _instance;
}
Better than manually locking would be to use Lazy, but that might be complicated if you need to pass parameters. If (as I assume) those parameters are only ever passed once, you might want to have a separate initialization function that will store those parameters so you don't need to pass them when you get your instance.
If the parameters are the same every time, you could maybe try something like this:
class HASPClass
{
private static ParameterObject _parameters;
private static Lazy<HASPClass> _instance = new Lazy<HASPClass>(() =>
{
if (_parameters == null)
{
throw new InvalidOperationException("Can get instance before initializing");
}
return new HASPClass(_parameters);
});
public static HASPClass Instance
{
get { return _instance.Value; }
}
private HASPClass(ParametersObject parameters)
{
// create and populate your object using values from parameters
}
public static void Initialize(ParameterObject parameters)
{
if (_parameters != null)
{
// you might throw an exception here if this is not allowed
// Or you might drop and recreate your object if it is allowed
}
_parameters = parameters;
}
}
You may or may not need to have locking around Initialize, but the idea would be that you'd probably call Initialize first from a parent thread so that it never needs to be called again from any other thread.
class HASPCLass
{
static SerialPort m_port;
HASPClass(..)
{
lock(m_port)
{
if (!Initialized())
{
Initialize();
}
}
}
void Close ()
{
lock(m_port)
{
if (Initialized())
{
Uninitialize();
}
}
}
}
Here is one more variant of the code for you. It should work in any case. It reopens the port in case of different baud rate requested.
class HASPCLass
{
private static SerialPort m_port;
private static bool m_initialized;
private static int m_baudRate;
public HASPClass(int baudRate)
{
lock(m_port)
{
if (!m_initialized)
{
Initialize(baudRate);
}
}
}
private Initialize()
{
m_port.open(baudRate);
m_baudRate = baudRate;
m_initialized = true;
}
private Uninitialize()
{
m_port.close();
m_initialized = false;
}
private ReinitializeIfNeeded(int baudRate)
{
if (baudRate != m_baudRate)
{
Uninitialize();
Initialize(baudRate);
}
}
public void Read(int baudRate, out buff)
{
lock(m_port)
{
ReinitializeIfNeeded(baudRate);
m_port.Read(out buff);
}
}
public void Write(int baudRate, in buff)
{
lock(m_port)
{
ReinitializeIfNeeded(baudRate);
m_port.Write(buff);
}
}
public void Close()
{
lock(m_port)
{
if (m_initialized)
{
Uninitialize();
}
}
}
}
First of all, I'm Java programmer and I'm new on C# and I need opinion of C# developers. I'm developing an application that connecting to database (firebird 1.5), query some data and return to me so there's nothing to be complicated but unfortunately I've stuck in some things :
As we know the database connection should be realised in separate thread cause it's a highweight operation and all the connections should be in connection pool in order to reuse already opened connection instead create the new one.
So here go my first question - how to organize connection pool properly?
(What about connection pool I've read that usually connection pool is already realised by data providers and I can just set it in connection parametres someway like "connectionBuilder.Pooling = true;")
What about queries? I mean that I've always use a Query per-Thread (and I think that is right cause we also do a highweight operation, am I wrong? Anyway I'd glad to see your best practices with organizing database work) and in Java I just do return Query result from separate thread by use an interfaces and anonymous classes like this:
In DBHelper.class (DBHelper is a singleton)
public interface QueryListener {
public void onSuccess(ArrayList<?>);
public void onError(Exception e);
}
public synchronized void getPromoActions(final QueryListener listener) {
if (listener != null) {
try {
ArrayList<String> myPromoActions;
.............
// some query's code
.....
listener.onSucces(myPromoActions);
} catch(Exception e) {
listener.onError(e);
} finally {
closeDatabase();
}
}
}
in some UI-class (for eaxample MainWindow)
public void getPromoActions(){
new Thread(new Runnable() {
#Override
public void run() {
DBHelper.getInstance().getPromoActions(new QueryListener() {
#Override
public void onSuccess(ArrayList<?>) {
// set Data to UI element such as Table
}
#Override
public void onError(Exception e){
// Handling exception
}
});
}
}).start();
}
In C# I should use delegates to mark which method will execute in thread, but unfortionally I can't send any callback as parameter - so how I should return my Query results to main UI thread?
UPD
I've understand a little bit how to work with delegates and events but have a problem with raising a custom event. I had declared an EventHandler and an custom EventArgs:
public delegate void QueryResultEventHandler(object sender, QueryResultEventArgs e);
public class QueryResultEventArgs : EventArgs
{
public List<String> QueryResult { get; set; }
public int QueryRecordsCount { get; set; }
}
And in My DBHelper.class I declared a next field and event:
private QueryResultEventHandler _queryResult;
public event QueryResultEventHandler onQueryResult
{
add
{
lock (this)
{
_queryResult += value;
}
}
remove
{
lock (this)
{
_queryResult -= value;
}
}
}
In UI class (MainWindow) I use next code:
public void GetAllDistricts() {
DBHelper.Instance.onQueryResult += new QueryResultEventHandler(GetAllDistricsResultHandler);
DBHelper.Instance.GetAllDistricts();
}
public void GetAllDistricsResultHandler(object sender, QueryResultEventArgs e){
// Here I'm adding the query result to Table
}
So my problem now is a how to raise an event asynchronously? In my DBHelper.class I'm trying to use beginInvoke&endInvoke with _query delegate but it seems that I had missed some code lines whatever it was I can't understand what I'm doing wrong an how to raise event asynchronously? Here my DBHelper.class code:
public void GetAllDistricts() {
try
{
if (_queryResult != null)
{
//** This code should run asynchronously ---------->
using (FbConnection connection = GetConnection())
{
FbCommand getAllDistrictsCommand = new FbCommand();
getAllDistrictsCommand.CommandText = "SELECT * FROM SEND";
getAllDistrictsCommand.Connection = connection;
QueryResultEventArgs args = new QueryResultEventArgs();
using (FbDataReader reader = getAllDistrictsCommand.ExecuteReader())
{
while (reader.Read())
{
//Here must be the processing of query results and filling the
//QueryResultEventArgs
args.QueryResult.Add(reader[0].ToString());
}
args.QueryRecordsCount = reader.GetInt32(reader.GetOrdinal("Rows"));
// And here after sucessfull query I should call OnQueryResult()
OnQueryResult(args);
}
}
//**<--------------------
}
else
{
throw new Exception("...Some exception message...");
}
}
catch (Exception e)
{
log.ErrorException(e.Message, e);
throw new Exception("...Some exception message...");;
}
finally {
CloseConnection();
}
}
// The QueryResultEvent method
protected void OnQueryResult(QueryResultEventArgs e)
{
if (_queryResult != null)
{
_queryResult(this, e);
}
}
First about connection pooling. If you will use ADO.NET then you do not need to worry about that, because it's already there. You don't need to do any extra work, you just create a connection:
using (var connection = new SqlConnection(connectionString))
{
// Queries to DB
}
You should always Close or Dispose you connections. The names of the methods look "scary" but actually connections are reused. Please read this MSDN article to get more details.
The code you proposed looks over-complicated. I think you should consider using async/await pattern which is in general not multithreaded, but it handles UI responsiveness issues and simplifies writing/reading of the code. In newer versions of .NET almost all methods that are potentially long to execute has async versions. So for example your data access layer might look like that (I'm using Dapper ORM's QueryAsync method just to keep code short and simple):
public async Task<IList<District>> GetAllDistrictsAsync()
{
using (var connection = await GetConnectionAsync())
{
return (await connection.QueryAsync<District>("select * from Districts")).ToList();
}
}
public async Task<IDbConnection> GetConnectionAsync()
{
var connectionString =
ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString;
var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
return connection;
}
And then somewhere on UI:
private async void Button_Click(object sender, EventArgs e)
{
var districts = await GetAllDistrictsAsync();
}
If you still need to execute some code in different thread you should look at Tasks namespace.
Task.Factory
.StartNew<IList<District>>(GetAllDistricts)
.ContinueWith(districts =>
{
// UI thread
}, TaskScheduler.FromCurrentSynchronizationContext());
In this example GetAllDistricts is not async and is executed in different thread. But ContinueWith will be executed in UI thread because of TaskScheduler.FromCurrentSynchronizationContext().
public void GetAllDistricts() {
DBHelper.Instance.onQueryResult +=
new QueryResultEventHandler(GetAllDistricsResultHandler);
new Thread(
new ThreadStart(DBHelper.Instance.GetAllDistricts)
).Start();
}
But the problem you will face is that you won't be able to access your UI controls from the EventHandler as it will be denied because you are not in the same thread anymore...
Refer to that article for some explanation
How to update the GUI from another thread in C#?
To avoid this you can maybe use the BackgroundWorker control.
Use this option
http://www.asp.net/mvc/overview/older-versions-1/models-(data)/creating-model-classes-with-the-entity-framework-cs
it is easy to use and easy to database operation with less code.
I'm developing a windows service with .NET framework 4.0 and C#.
This service will open a socket to receive commands.
I have this socket listener class:
public class SocketListener
{
private System.Net.Sockets.TcpListener m_server;
public SQLServerSocketListener()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 5445);
m_server = new System.Net.Sockets.TcpListener(ip);
}
public void Start()
{
m_server.Start();
m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}
public void Stop()
{
if (m_server != null)
m_server.Stop();
}
private void Callback(IAsyncResult ar)
{
if (!(m_server.Server.IsBound) ||
(m_server.Server == null))
return;
TcpClient client;
try
{
client = m_server.EndAcceptTcpClient(ar);
}
catch (ObjectDisposedException)
{
//Listener canceled
return;
}
DataHandler dataHandler = new DataHandler(client);
ThreadPool.QueueUserWorkItem(dataHandler.HandleClient, client);
m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}
}
And this class to process the commands received through the socket:
class DataHandler
{
private bool m_disposed = false;
private TcpClient m_controlClient;
private IPEndPoint m_remoteEndPoint;
private string m_clientIP;
private NetworkStream m_controlStream;
private StreamReader m_controlReader;
public DataHandler(TcpClient client)
{
m_controlClient = client;
}
public void HandleClient(object obj)
{
m_remoteEndPoint = (IPEndPoint)m_controlClient.Client.RemoteEndPoint;
m_clientIP = m_remoteEndPoint.Address.ToString();
m_controlStream = m_controlClient.GetStream();
m_controlReader = new StreamReader(m_controlStream, true);
string line;
try
{
while (((line = m_controlReader.ReadLine()) != null) ||
(m_controlClient == null) ||
(!m_controlClient.Connected))
{
CommandHandler.ProcessCommand(line);
}
}
catch (Exception ex)
{
Console.WriteLine("CodeServerService.DataHandler error: {0}", ex.Message);
}
finally
{
Dispose();
}
}
}
And, the CommandHandler:
class CommandHandler
{
public static void ProcessCommand(string command, string connStringINICIC, string connStringTRZIC, byte codeLevel)
{
switch (command)
{
case "GetNewCodes<EOF>":
CodesIncremental.GetNewCodes();
break;
}
}
}
And CodesIncremental:
public class CodesIncremental
{
public static bool GetNewCodes()
{
[ ... ]
}
}
My problem is that I can receive GetNewCodes<EOF> command before the first one finish. So, I need to don't let GetNewCodes<EOF>runs if there is another GetNewCodes<EOF> running.
How can I don't let run CodesIncremental.GetNewCodes(); if this code its running in another thread?
I need something to discard the commands received while CodesIncremental.GetNewCodes(); is running.
In pseudo code:
If CodesIncremental.GetNewCodes(); is running do nothing.
This version does not block. CompareExchange ensures atomicity, so only one thread will swap the value of the _running variable, the rest of threads will just return inmediately.
public class CodesIncremental
{
static Int32 _running = 0;
public static bool GetNewCodes()
{
if (Interlocked.CompareExchange(ref _running, 1, 0) == 1)
return false;
try
{
// Do stuff...
return true;
}
finally
{
_running = 0;
}
}
}
A difference than monitors or other synchronization methods, there is little contention on this method, and it is quite faster.
Maybe like this using AutoResetEvent:
public class CodesIncremental
{
private AutoResetEvent _event = new AutoResetEvent(true);
public static bool GetNewCodes()
{
if(!_event.WaitOne(0))
return true; //is running
try
{
/*
actions in case if isn't running
*/
}
finally
{
_event.Set();
}
return false;
}
}
EDIT: Update to address the modification of the question.
A simple way is to use the Monitor.TryEnter and Monitor.Exit
Just call the ExecuteGetNewCodeCommand for the processing of your "GetNewCode" command.
object _myLock = new object();
void ExecuteGetNewCodeCommand( ArgType args)
{
bool result = false;
try
{
result = Monitor.TryEnter(_myLock); // This method returns immediately
if( !result) // check if the lock is acquired.
return;
// Execute your command code here
}
finally
{
if(result) // release the lock.
Monitor.Exit(_myLock);
}
}
Old answer (before the modification of the question):
Think about using a queue and a Thread Pool.
Every time you receive a new Command (including "GetNewCode") insert it into a queue. In addition, you will have a Thread Pool that will read requests from the queue and execute them.
If you are using only one thread in the Thread pool, or a dedicated thread for this type of commands (where there are other threads for other requests/commands in the queue/queus), then only one "GetNewCode" request will be running at the same time.
This way you can control the number of threads your server will run. Thus, also the resources your server uses.
If you just synchronize (via locks or other mechanism) then there are a performance penalties. And maybe a denial of service, if you reached a thread limit. Let's say for somehow the execution of a request is taking too long (Maybe a deadlock in your code). If you will not use a Thread pool, and will execute the commands/requests on the same thread the client connected to your, then your sever may hang.
Though, If you will synchronize the threads inside the thread pool, then the server will not hang. Maybe it will be really slow to execute the requests, but it will still run and work.
There is a default .Net ThreadPool implementation at MSDN.
Add a lock to your CodesIncremental Class:
public class CodesIncremental
{
private object m_threadLock = new object();
public static bool GetNewCodes()
{
lock(m_threadLock)
{
[ ... ]
}
}
}
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
This way when your GetNewCodes method is called the first time the 'lock' statement will get an exclusive lock on the 'm_threadLock' object and only release it when the execution leaves the lock block, if any other thread calls the methods while the first thread is still inside the lock block it will not be able to get an exclusive lock and execution will suspend until it can.
Update:
Since you want to discard other calls try this:
public class CodesIncremental
{
private static object m_threadLock = new object();
private static bool m_running = false;
public static bool GetNewCodes()
{
lock(m_threadLock)
{
if(m_running)
{
return;
}
m_running = true;
}
try
{
[ ... ]
}
finally
{
m_running = false;
}
}
}
there might be better ways but this should do the trick.
Update 2: Hadn't seen the static
There is an application that collects news from rss of news agencies maybe like Google Reader!.
I want to call a method to update my links in DB in a period of the time and it continues to the Application life time.
something like a clock !!!
without any pause
I know some info about Threading
but the problem is :
Where can I call my Update method?
I have some classes that some of them derive from others and I use to layer in my Project
I call the method in Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(UpdateRss));
thread.Start();
Thread.Sleep(1000);
}
public void UpdateRss()
{
while (true)
{
using (LinkService linkSrv = new LinkService())
{
linkSrv.UpdateLinksFromRSS();
}
}
}
and the definition of UpdateLinksFromRSS in LinkService is:
public void UpdateLinksFromRSS()
{
List<RssInfo> q;
using (RssService RssSrv = new RssService())
{
q = RssSrv.GetRssInfoes();
}
foreach (var item in q)
{
AddLink(item);
}
}
Honestly the problem is i have a property in BaseService that is defined like this:
public static System.Web.Caching.Cache Cache
{
get { return HttpContext.Current.Cache; }
}
when I run the project!
I got an error from this line: return HttpContext.Current.Cache;