Here is the code for my initializer:
public void Initialize(MainActivity activity)
{
context = activity;
store = activity.store;
gui = activity.gui;
store.Initialize(activity);
initialized = true; // note the this is initialized to TRUE
}
Here is the code for my class constructor:
public TextReceiver()
{
Android.Util.Log.Debug("DEBUG", "CREATED a receiver :" + counter.ToString());
toKill = counter++;
}
Here is the code for my work-around:
public void Refresh()
{
initialized = true;
store = context.store;
gui = context.gui;
}
Here is the code for my callback:
public override void OnReceive(Context contextPass, Intent intent)
{
Android.Util.Log.Debug("DEBUG", "receiving a text message: initialized - [" + initialized.ToString() + "]");
if (initialized == false) { Refresh(); } // this is my current work-around
// but I fear this leaks memory
if (intent.HasExtra("pdus") && (ContextCompat.CheckSelfPermission(context, Manifest.Permission.ReadSms) == Permission.Granted))
{
Bundle MessageInfo = intent.Extras;
Java.Lang.Object[] pdus = (Java.Lang.Object[])MessageInfo.Get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.Length];
for (int i = 0; i < messages.Length; i++)
{
SmsMessage toSend = null;
// Verizon phones use the string "3gpp2"
// Some other carriers use the sting
// "3gpp". If the version is not correct,
// this section will throw an exeception
try { toSend = SmsMessage.CreateFromPdu((byte[])(pdus[i]), "3gpp2"); }
catch { toSend = SmsMessage.CreateFromPdu((byte[])(pdus[i]), "3gpp"); }
if (store.Push(toSend) == true) // checks for duplicates
{
gui.TextsReceived();
}
}
}
}
The log file is large, but here is the significant section:
11-13 14:10:50.984 Google Pixel 3 Error 26765 Bugle zdt: Jibe SDK Service not available. Is the Jibe SDK service running? Did you call connect() and wait for the notification before calling an API function?
Note that the bug report mentions a service which is not running:
Is the Jibe SDK service running?
Did you call connect() and wait for the notification before calling an API function?
Is this a result of the way I am using the callback? Am I calling the callback improperly somehow?
My work-around works, but I fear it leaks memory because it instantiates a new BroadcastReciever with each callback and doesn't ever free the instance as far as I can tell.
Some more details:
I'm initializing and starting five threads in my Testing Class:
[Test]
public void ReportGeneratorFiveThreadTest()
{
var threads = new List<ReportGeneratorThread>();
var logger = new Log4NetLogger(typeof(ReportGeneratorThreadTest));
for (var i = 0; i < 5; i++)
{
var estimatedReportSize = EstimatedReportSize.Normal;
var thread = new ReportGeneratorThread(logger, new ReportGenerator(20), estimatedReportSize, new ManualResetEvent(false));
thread.Name = string.Format("ReportGeneratorThread{0}", i);
threads.Add(thread);
}
threads.ForEach(t => t.Start());
}
And I'm starting all threads by calling following method in ReportGeneratorThread class:
public void Start()
{
this.running = true;
this.t = new Thread(this.GenerateReport());
this.t.SetApartmentState(ApartmentState.STA);
this.t.Start();
}
Which calls a GenerateReport() method in order to perform an operation:
public void GenerateReport()
{
var didwork = false;
try
{
didwork = this.reportGenerator.GenerateReport(this.estimatedReportSize);
}
catch (Exception e)
{
this.log.LogError(ReportGenerator.CorrelationIdForPickingReport, string.Format(CultureInfo.InvariantCulture, "System"), string.Format(CultureInfo.InvariantCulture, "Error during report generation."), 0, e);
this.doneEvent.Reset();
Debug.WriteLine("Thread is aborted !!!");
}
finally
{
if (!didwork)
{
Thread.Sleep(Settings.Default.ReportGenerationInterval);
}
}
}
My purpose is to inform my main thread once a thread among all five threads gets aborted (an exception is thrown in GenerateReport() method) and restart it in my main thread afterwards. I have tried using ManualResetEvent for that purpose, but it seems like it is not the proper class to use for this purpose. Any approaches ?.
I would like to delete the Dead Lettered messages from the service bus queue. In particular, this value is called DeadLetterMessageCount and you can find out this by right-clicking the "Properties" of the SB queue in the Server Explorer of your project (in case of using a SB queue).
The reason I would like to do this is because I've set up an Autoscale of the cloud service. So, when the SB queue is quite big, it adds some more cores in order to proceed the messages faster (it enables more worker roles). I realized that when you set up the scaling depending on the number of messages in the queue, it counts the DeadLettered messages as well (messages that cannot be consumed).
So that's a waste of money, as more instances are enabled that are not needed.
Any queries, please let me know.
Thanks for your help
You read and delete messages from dead letter queue the same way you read from normal queues or subscriptions.
You can use this method to get the path of the queue: QueueClient.FormatDeadLetterPath(queuePath).
Also see this previous answer: How do I delete a DeadLetter message on an Azure Service Bus Topic
This is a code to delete a Dead-Letter messages from Queues.
public async void DeleteMessagesFromQueueAsync()
{
bool isDeadLetter=true;
long SequenceNumber = 12;
string queuePath='queue name';
string connectionString='connection string of ASB Namespace';
BrokeredMessage _srcMessage = null;
DeleteMessageResponse _msgDeletionStatus = new DeleteMessageResponse();
MessageReceiver fromQueueClient = null;
try
{
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);
string _fromEntityPath = !isDeadLetter ? queuePath : QueueClient.FormatDeadLetterPath(queuePath);
fromQueueClient = await factory.CreateMessageReceiverAsync(_fromEntityPath, ReceiveMode.PeekLock);
BrokeredMessage _message = await fromQueueClient.ReceiveAsync(SequenceNumber);
if (_message != null)
_srcMessage= _message;
if (_srcMessage != null )
{
await _srcMessage.CompleteAsync();
}
}
catch (Exception ex)
{
}
finally
{
if (fromQueueClient != null)
await fromQueueClient.CloseAsync();
}
}
You can use 'ReceiveAndDelete' mode and 'ReceiveBatchAsync' to delete quickly from DeadLetterQueue
private async void button1_Click(object sender, EventArgs e)
{
try
{
var DLQPath = "/$DeadLetterQueue"; ///**** Important - Pointing to DLQ'
var topicName = "message";
var sub = "message-subscription";
int batchSize = 100;
runProcess = true;
_subscriptionClient = SubscriptionClient.CreateFromConnectionString(connectionSt, topicName, sub + DLQPath, ReceiveMode.ReceiveAndDelete);
int cnt = 0;
do
{
var messages = await _subscriptionClient.ReceiveBatchAsync(batchSize);
var msgCount = messages.Count();
if (msgCount == 0)
{
break;
}
cnt += msgCount;
labelCount.Text = cnt.ToString();
}
while (runProcess);
_subscriptionClient.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.GetBaseException().Message);
return;
}
}
I created a thread in C # 4.0 and would like to know how do I check if it is running?
You can use Thread.IsAlive to check to see if a Thread is running.
That being said, if you're using C# 4, it's rarely a good idea to make "threads" manually. You should consider using the TPL and the Task/Task<T> class, as this provides a much cleaner model to attach work to run after the task completes, pull data out of the operation, etc.
I use Mutex to verify this. Sometimes just verify is Thread is alive with Thread.IsAlive is not safe if you are running on Background.
Try this:
private void btnDoSomething()
{
try
{
string nameThread = "testThreadDoSomething";
var newThread = new Thread(delegate() { this.DoSomething(nameThread); });
newThread.IsBackground = true;
newThread.Name = nameThread;
newThread.Start();
//Prevent optimization from setting the field before calling Start
Thread.MemoryBarrier();
}
catch (Exception ex)
{
}
}
public void DoSomething(string threadName)
{
bool ownsMutex;
using (Mutex mutex = new Mutex(true, threadName, out ownsMutex))
{
if (ownsMutex)
{
Thread.Sleep(300000); // 300 seconds
if (Monitor.TryEnter(this, 300))
{
try
{
// Your Source
}
catch (Exception e)
{
string mensagem = "Error : " + e.ToString();
}
finally
{
Monitor.Exit(this);
}
}
//mutex.ReleaseMutex();
}
}
}
For my network based project I need to lock some codes to prevent simultaneous access.
This is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utility;
using DataBaseConnection;
using System.Net.Sockets;
using System.Data;
using System.IO;
namespace SunHavenClasses
{
public delegate void CtatReceiveDelegate(string message);
public class ServerHandlerClass
{
public event CtatReceiveDelegate OnChatDataReceive;
private Settings settings;
private DBCon con;
private Utility.Network.Server server;
private Dictionary<string, Socket> UsersOnline;
private Dictionary<string, int> unAuthenticatedIps;
private string pass = "logisoftlogicielbarundipankar";
public ServerHandlerClass(Settings s)
{
settings = s;
con = s.GetConnection();
server = new Utility.Network.Server(7777);
server.ClientConnectEventArise += OnUserConnect;//.OnClientConnect(OnUserConnect);
server.ClientDataReceiveEventArise += OnUsersDataReceive;
server.ClientDataSendEventArise += OnDataSendToUser;
server.ClientDisconnectEventArise += OnUserDisconnect;
server.OnBlockUser += OnUserBlocked;
UsersOnline = new Dictionary<string, Socket>();
unAuthenticatedIps = new Dictionary<string, int>();
}
private void OnUserConnect(Utility.Network.ServerEventArguments e)
{
Stream data = Utility.Serializing.Serialize(settings);
data = ZipNEncrypt.Zip(new string[] { "settings" }, new Stream[] { data }, pass);
server.Send(data, e.ClientSocket);
//MessageBox.Show(e.ClientSocket.RemoteEndPoint.ToString() + " is Connected!!");
}
private void OnUsersDataReceive(Utility.Network.ServerEventArguments e)
{
Dictionary<string, System.IO.Stream> data = ZipNEncrypt.Unzip(e.Data, pass);
User user;
try
{
user = (User)Serializing.Deserialize(data["user"]);
if (!UsersOnline.ContainsKey(user.GetUserId()))
{
server.BlockIp(e.ClientSocket);
return;
}
data.Remove("user");
}
catch (Exception)
{
bool passed = true;
foreach (string key in data.Keys)
{
if (key.Equals("LoggedIn")) break;
string[] str = key.Split('_');
if (str[0].Equals("GetData"))
{
string strr = (string)Serializing.Deserialize(data[key]);
if (strr.Contains("Users"))
{
string ip = e.ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
/*CHANGE 1.2.10 00:14*/
lock (unAuthenticatedIps)
{
if (!unAuthenticatedIps.ContainsKey(ip))
{
unAuthenticatedIps.Add(ip, 1);
}
else unAuthenticatedIps[ip] += 1;
if (unAuthenticatedIps[ip] >= 11) passed = false;
}
/*CHANGE 1.2.10 00:14*/
break;
}
else passed = false;//server.AddBlockedIp(ip);
}
else passed = false;
}
if (!passed)
{
server.BlockIp(e.ClientSocket);
}
}
foreach (string key in data.Keys)
{
if (key.Equals("LoggedIn"))
{
try
{
User u = (User)Serializing.Deserialize(data["LoggedIn"]);
if (!UsersOnline.ContainsKey(u.GetUserId()))
{
if (User.ValidateUser(u.GetUserId(), u.GetPassword(), con))
{
/*CHANGE 1.2.10 00:14*/
lock (UsersOnline)
{
UsersOnline.Add(u.GetUserId(), e.ClientSocket);
string ip = e.ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
Utility.Log.Write("UserLog.log", u.GetUserId() +
" Logged In From Ip " + ip);
}
/*CHANGE 1.2.10 00:14*/
}
else
{
server.BlockIp(e.ClientSocket);
return;
}
}
else
{
Stream tmpStream = Serializing.Serialize("Same User");
tmpStream = ZipNEncrypt.Zip(new string[] { key + "ERROR_SameUser" },
new Stream[] { tmpStream }, pass);
server.Send(tmpStream, e.ClientSocket);
return;
}
}
catch (Exception) { }
return;
}
else if (key.Equals("chat"))
{
string ip = e.ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
string message = ip + " : "+ (string)Serializing.Deserialize(data[key]);
OnChatDataReceive(message);
return;
}
string[] str = key.Split('_');
Stream dataStream = null;
object obj = null;
try
{
if (str[0].StartsWith("Get"))
{
if (str[0].Equals("GetData"))
{
string query = (string)Serializing.Deserialize(data[key]);
obj = con.GetData(query);
}
else if (str[0].Equals("GetColumn"))
{
string query = (string)Serializing.Deserialize(data[key]);
string[] tmp = query.Split('%');
obj = con.GetColumn(tmp[0], tmp[1]);
}
else if (str[0].Equals("GetColumnDistrinctValue"))
{
string query = (string)Serializing.Deserialize(data[key]);
string[] tmp = query.Split('%');
obj = con.GetColumnDistrinctValue(tmp[0], tmp[1]);
}
}
else
{
lock (this)
{
if (str[0].Equals("ExecuteUpdate"))
{
if (str[1].Equals("Query"))
{
Query query = (Query)Serializing.Deserialize(data[key]);
obj = con.ExecuteUpdate(query);
}
else if (str[1].Equals("String"))
{
string query = (string)Serializing.Deserialize(data[key]);
obj = con.ExecuteUpdate(query);
}
}
else if (str[0].Equals("ExecuteBatchUpdate"))
{
if (str[1].Equals("Query"))
{
Query[] query = (Query[])Serializing.Deserialize(data[key]);
obj = con.ExecuteBatchUpdate(query);
}
else if (str[1].Equals("String"))
{
string[] query = (string[])Serializing.Deserialize(data[key]);
obj = con.ExecuteBatchUpdate(query);
}
}
else if (str[0].Equals("ExecutrInsert"))
{
Query query = (Query)Serializing.Deserialize(data[key]);
obj = con.ExecutrInsert(query);
}
}
}
dataStream = Serializing.Serialize(obj);
dataStream = ZipNEncrypt.Zip(new string[] { key },
new Stream[] { dataStream }, pass);
}
catch (Exception ex)
{
dataStream = Serializing.Serialize(ex.Message);
dataStream = ZipNEncrypt.Zip(new string[] { key + "_ERROR" },
new Stream[] { dataStream }, pass);
}
server.Send(dataStream, e.ClientSocket);
}
}
private void OnDataSendToUser(Utility.Network.ServerEventArguments e)
{
}
private void OnUserDisconnect(Utility.Network.ServerEventArguments e)
{
//System.Windows.Forms.MessageBox.Show("Disconnected");
string ip = e.ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
/*CHANGE 1.2.10 00:14*/
lock (unAuthenticatedIps)
{
if (unAuthenticatedIps.ContainsKey(ip))
unAuthenticatedIps.Remove(ip);
}
lock (UsersOnline)
{
foreach (string key in UsersOnline.Keys)
if (UsersOnline[key].Equals(e.ClientSocket))
{
Utility.Log.Write("UserLog.log", key + " Logged Out From Ip " + ip);
UsersOnline.Remove(key);
break;
}
}
/*CHANGE 1.2.10 00:14*/
}
private void OnUserBlocked(Utility.Network.ServerEventArguments e)
{
string ip = e.ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
Utility.Log.Write("UserLog.log", "Blocked For Illegal Access From Ip " + ip);
}
public void Send(Stream dataStream)
{
foreach (string key in UsersOnline.Keys)
{
try
{
server.Send(dataStream, UsersOnline[key]);
}
catch (Exception) { }
}
}
public void Send(Stream dataStream, Socket client)
{
try
{
server.Send(dataStream, client);
}
catch (Exception) { }
}
/*changed*/
public bool AddUser(string userId, Socket socket)
{
if (UsersOnline.ContainsKey(userId)) return false;
UsersOnline.Add(userId, null);
return true;
}
public void RemoveUser(string userId)
{
if (!UsersOnline.ContainsKey(userId) || UsersOnline[userId] != null) return;
UsersOnline.Remove(userId);
}
}
}
Now I am not sure that I am using lock correctly.Please Give me some advice.
Thanks.
I'm guessing you read a lot more than you write? If so, a ReaderWriterLockSlim may be more appropriate to reduce blocking (take read when you just want to check for the key, and write to manipulate the data).
By that I mean you could do double-checked locking with a read at first, then if it fails take a write lock, check again and add if necessary.
Also - the lock(this) is generally frowned upon; having a separate lock object is preferred.
Note that to be effective, all access must respect the lock; there are some places where UsersOnline is locked, and some places where it is accessed without a lock, for example; those second cases may explode in a gooey mess.
For example:
if (!UsersOnline.ContainsKey(u.GetUserId()))
{
if (User.ValidateUser(u.GetUserId(), u.GetPassword(), con))
{
/*CHANGE 1.2.10 00:14*/
lock (UsersOnline)
{
UsersOnline.Add(u.GetUserId(), e.ClientSocket);
In the above, if it is possible that two threads are looking at UsersOnline, then you've already failed by attempting ContainsKey without the lock. If another thread is mutating the state when you do this.... boom.
First of all, you code isn't thread safe at all. In your code you locks only modifying operations (Remove, Add), but also you should lock all access to shared fields. Actually this code not thread safe at all. I think that in this case ReaderWriterLockSlim - would be the best choise.
Second. lock(this) - very bed idea. You should use special objects for this.
Finally, I think your code is messy and hard to understand. Maybe your class solve many different tasks. Maybe you should extract some logic to separate classes (for example create guarded dictionaries as separate classes) or something else.
Sample of using ReaderWriterLockSlim:
someSharedResource;
someSharedResourceRWLock = new ReaderWriterLockSlim();
Some reading code:
try
{
someSharedResourceRWLock.EnterReadLock();
//access to someSharedResource for reading
}
finally
{
someSharedResourceRWLock.ExitReadLock();
}
Some writing code:
try
{
someSharedResourceRWLock.EnterWriteLock();
//access to someSharedResource for modifications
}
finally
{
someSharedResourceRWLock.ExitWriteLock();
}
You are using it correctly some of the time. unAuthenticatedIps is being protected correctly, but UsersOnline is not. Let's consider two parallel threads passing through your code:
Thread A Thread B
-------- --------
if (!UsersOnline.ContainsKey(u.GetUserId()) Statement's true Statement's true
{
lock (UsersOnline) Get lock Block
{
UsersOnline.Add UsersOnline.Add
} Release Lock
} Get lock
UsersOnline.Add
Release lock
Notice that both threads A and B modify the UsersOnline dictionary. This structure would properly protect that object:
if (!UsersOnline.ContainsKey(u.GetUserId()))
{
if (User.ValidateUser(u.GetUserId(), u.GetPassword(), con))
{
lock (UsersOnline)
{
// Note the additional check in case another thread
// added this already
if (!UsersOnline.ContainsKey(u.GetUserId())
{
UsersOnline.Add(u.GetUserId(), e.ClientSocket);
// ...
}
}
}
else
{
server.BlockIp(e.ClientSocket);
return;
}
}
As far as the last lock goes (lock (this)), I don't yet see why you would need it. str and obj are both local variables, so you shouldn't need to worry about them being modified by separate threads. And, as other have stated, locking this is not recommended.
The advice given so far has been great, but I have a design suggestion you may want to consider. Replace this:
private Dictionary<string, Socket> UsersOnline;
with a custom Thread Safe Dictionary
private ThreadSafeDictionary<string, Socket> UsersOnline
If its a fit for your needs, it would be a nice way to separate the business logic from the threading logic.