Microsoft Messaging Queue ReceiveCompleted Event - c#

i have a console applicaiton . in this application i make contact with a queue. first i check to see if for example queue with name 'exampleQueue' exists or not. and if it does not exist i create it.
after creating and returing the path or just returning the path . i want to attach the ReceiveCompleted event to this queue.
i have two approach i can use 'using' keyword to make the queue dispoed after my work or i can just use normal way to create queue object .
in below u can see my code :
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CreateQueue(".\\exampleQueue", false);
using (var queue = new MessageQueue(".\\exampleQueue"))
{
queue.ReceiveCompleted += MyReceiveCompleted;
queue.BeginReceive();
}
}
public static void CreateQueue(string queuePath, bool transactional)
{
if (!MessageQueue.Exists(queuePath))
{
MessageQueue.Create(queuePath, transactional);
}
else
{
Console.WriteLine(queuePath + " already exists.");
}
}
private static void MyReceiveCompleted(Object source,
ReceiveCompletedEventArgs asyncResult)
{
var queue = (MessageQueue)source;
try
{
var msg = queue.EndReceive(asyncResult.AsyncResult);
Console.WriteLine("Message body: {0}", (string)msg.Body);
queue.BeginReceive();
}
catch (Exception ex)
{
var s = ex;
}
finally
{
queue.BeginReceive();
}
return;
}
}
}
the problem that i face is that whenever i use this code for create queue object
using (var queue = new MessageQueue(".\\exampleQueue"))
{
queue.ReceiveCompleted += MyReceiveCompleted;
queue.BeginReceive();
}
the MyReceiveCompleted event does not work properly .
but when i use this
var queue = new MessageQueue(".\\exampleQueue");
queue.ReceiveCompleted += MyReceiveCompleted;
queue.BeginReceive();
every thing just work in proper way.
my question is that which approcah is the best one ?
and if i choose to use the first approcah , how can i make it work ?
accept my apologize for bad typing .

You can use your original approach, but you have to make sure, that the Main method is blocking inside the using statement:
static void Main(string[] args)
{
CreateQueue(".\\exampleQueue", false);
using (var queue = new MessageQueue(".\\exampleQueue"))
{
queue.ReceiveCompleted += MyReceiveCompleted;
queue.BeginReceive();
// here you have to insert code to block the
// execution of the Main method.
// Something like:
while(Console.ReadLine() != "exit")
{
// do nothing
}
}
}

Related

System.Threading.Task not starting in production environment

I have a c# windows service which is doing various tasks. Its working perfectly on my local system but as soon as I start it on my product server, its doesn't perform a particular task on it.
This is how my service is structured:
public static void Execute()
{
try
{
// .... some work ....
foreach (DataRow dr in dt.Rows)
{
string cc = dr["ccode"].ToString();
Task objTask = new Task(delegate { RequestForEachCustomer(cc); });
objTask.Start();
}
}
catch (Exception ex)
{
// Logging in DB + Text File
}
}
public static void RequestForEachCustomer(object cc)
{
try
{
// .... some work ....
foreach (DataRow dr in dt.Rows)
{
WriteLog("RequestForEachCustomer - Before Task");
Task objTask = new Task(delegate { RequestProcessing(dr); });
objTask.Start();
WriteLog("RequestForEachCustomer - After Task");
}
}
catch (Exception ex)
{
// Logging in DB + Text File
}
}
public static void RequestProcessing(object dr)
{
try
{
WriteLog("Inside RequestProcessing");
// .... some work ....
}
catch (Exception ex)
{
// Logging in DB + Text File
}
}
Now what happens on the production server is that it logs the last entry in RequestForEachCustomer which is "RequestForEachCustomer - After Task" but it doesn't log the entry from RequestProcessing which mean the task is not starting at all. There are no exceptions in either database or text file.
There are no events logged in window's event viewer either. Also the service keeps working (if I insert another record in database, its processed by the service immediately so the service isn't stuck either. It just doesn't seem to process RequestProcessing task.)
I am baffled by this and it would be great if someone could point out the mistake I am making. Oh, btw did I forgot to mention that this service was working perfectly few days ago on the server and it is still working fine on my local PC.
EDIT :
WriteLog :
public static void WriteErrorLog(string Message)
{
StreamWriter sw = null;
try
{
lock (locker)
{
sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\LogFile.txt", true);
sw.WriteLine(DateTime.Now.ToString() + ": " + Message);
sw.Flush();
sw.Close();
}
}
catch (Exception excep)
{
try
{
// .... Inserting ErrorLog in DB ....
}
catch
{
throw excep;
}
throw excep;
}
}
I have also logged an entry on OnStop() something like "Service Stopped" and its logs every time I stop my service so the problem couldn't exist in WriteLog function.
I suggest you refactor your code as in this MSDN example. What bother me in your code is, you never wait for tasks to finish anywhere.
The following example starts 10 tasks, each of which is passed an index as a state object. Tasks with an index from two to five throw exceptions. The call to the WaitAll method wraps all exceptions in an AggregateException object and propagates it to the calling thread.
Source : Task.WaitAll Method (Task[])
This line from example might be of some importance :
Task.WaitAll(tasks.ToArray());

Get data from tcp listener callback in the main thread

I've created a transparent proxy for fixing the incoming data, but I want to have all the data from the listening callback in the main thread (where I've opened the socket). What's the best way to do it in the C#?
I am using the library TrotiNet plus some rewriting logic - fixing the response header. The simple code - as follows
using System;
using TrotiNet;
namespace TrotiNet.Example
{
public class TransparentProxy : ProxyLogic
{
public TransparentProxy(HttpSocket clientSocket)
: base(clientSocket) { }
static new public TransparentProxy CreateProxy(HttpSocket clientSocket)
{
return new TransparentProxy(clientSocket);
}
protected override void OnReceiveRequest()
{
Console.WriteLine("-> " + RequestLine + " from HTTP referer " +
RequestHeaders.Referer);
}
protected override void OnReceiveResponse()
{
Console.WriteLine("<- " + ResponseStatusLine +
" with HTTP Content-Length: " +
(ResponseHeaders.ContentLength ?? 0));
}
}
public static class Example
{
public static void Main()
{
int port = 12345;
bool bUseIPv6 = false;
var Server = new TcpServer(port, bUseIPv6);
Server.Start(TransparentProxy.CreateProxy);
Server.InitListenFinished.WaitOne();
if (Server.InitListenException != null)
throw Server.InitListenException;
while (true)
{
//need to get the response data here
System.Threading.Thread.Sleep(1000);
}
//Server.Stop();
}
}
}
So mainly, I need to get all the data that comes to OnReceiveResponse in the main thread (Example.Main executor). I do such a proxy for one call - so data not more than 1kB.
Probably you fit in producer/consumer pattern, try to use BlockingCollection it support "Concurrent adding and taking of items from multiple threads"
(https://msdn.microsoft.com/en-us/library/dd997371(v=vs.110).aspx) like this:
BlockingCollection<Data> dataItems = new BlockingCollection<Data>(100);
in your dataReceiver handler do
dataItems.Add(data);
in your main thread consumer:
data = dataItems.Take();
Also better to replace infinity loop with sleep to Console.Readkey()

Class Inheriting from Mainwindow causes "the calling thread must be sta because many UI components require this"

I'm working on a Chat server which receives connections from multiple clients and sends/receives messages.
This is how it gets connections from the clients:
public void StartServer()
{
tcpListener = new TcpListener(IPAddress.Any, 60000);
tcpListener.Start();
listenTask = Task.Factory.StartNew(() => ListenLoop());
}
private async void ListenLoop()
{
int i = 0;
for (; ; )
{
var socket = await _tcpListener.AcceptSocketAsync();
if (socket == null)
break;
var c = new Client(socket, i);
i++;
}
}////Got this code from somewhere here, not really what I want to use (discussed down)
This is the Client class:
public class Client
{
//irrelevant stuff here//
public Client(Socket socket, int number)
{
//irrelevant stuff here//
Thread ct = new Thread(this.run);
ct.Start();
}
public void run()
{
writer.Write("connected"); //Testing connection
while (true)
{
try
{
string read = reader.ReadString();
// Dispatcher.Invoke(new DisplayDelegate(DisplayMessage), new object[] { "[Client] : " + read });
}////////Not working, because Client needs to inherit from MainWindow.
catch (Exception z)
{
MessageBox.Show(z.Message);
}
}
}
}
Ok so problem is, to update the UI Client class must inherit from MainWindow, but when it does, I get "the calling thread must be sta because many UI components require this" error. When it doesn't inherit it works just fine.
Another problem is, I want to use a Client[] clients array and then when a user connects, it adds him to the array so that i can individually write/read to/from specific clients.
while (true)
{
try
{
clients[counter] = new Client(listener.AcceptSocket(), counter);
counter ++;
MessageBox.Show("client " + counter.ToString());
}
catch (Exception e) { MessageBox.Show(e.Message); }
}
Problem here is, i get "Object refrence not set to an instance of an object" when a client connects.
Any ideas how to fix both/any of these problems?
Sorry code might be a bit messed up but I tried lots of stuff to get it working so I ended up with lots of junk in the code.
Thanks in advance.

EWS managed API streaming notification ...NewMail watcher using C# maildeleted event is not notified

.Net application which will subscribe to streaming notification. This application executes well, this subscription disconnected after 30 mints so I added the code to reconnect the connection .I tested the application by adding break point at the reconnect line and waited for some time before it established the connection again. During that time I created a few new emails and watched if console displays those events. It did not as connection was disconnected then I run the code again and I was able to see the events which were created during the time connection disconnected and connected. I need to know if this is the right way to make this process run continuously and track the events which occurred during the disconnect and reconnect of the application. also need to know why the below code is not notifying about delete mail event. kindly looking for help.
namespace NewMailNotification
{
class Program
{
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
//***********New**********************
ExchangeService mailbox = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
string mailboxEmail = ConfigurationSettings.AppSettings["user-id"];
WebCredentials wbcred = new WebCredentials(ConfigurationSettings.AppSettings["user"], ConfigurationSettings.AppSettings["PWD"]);
mailbox.Credentials = wbcred;
// mailbox.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxEmail);
mailbox.AutodiscoverUrl(mailboxEmail, RedirectionUrlValidationCallback);
mailbox.HttpHeaders.Add("X-AnchorMailBox", mailboxEmail);
FolderId mb1Inbox = new FolderId(WellKnownFolderName.Inbox, mailboxEmail);
SetStreamingNotification(mailbox, mb1Inbox);
bool run = true;
bool reconnect = false;
while (run)
{
System.Threading.Thread.Sleep(100);
}
}
internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
//The default for the validation callback is to reject the URL
bool result=false;
Uri redirectionUri=new Uri(redirectionUrl);
if(redirectionUri.Scheme=="https")
{
result=true;
}
return result;
}
static void SetStreamingNotification(ExchangeService service,FolderId fldId)
{
StreamingSubscription streamingssubscription=service.SubscribeToStreamingNotifications(new FolderId[]{fldId},
EventType.NewMail,
EventType.Created,
EventType.Deleted);
StreamingSubscriptionConnection connection=new StreamingSubscriptionConnection(service,30);
connection.AddSubscription(streamingssubscription);
//Delagate event handlers
connection.OnNotificationEvent+=new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(Connection_OnDisconnect);
connection.OnSubscriptionError+=new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
connection.Open();
}
static private void Connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
if (!connection.IsOpen)
{
// Console.WriteLine("no connection");
connection.Open();
}
}
static void OnEvent(object sender,NotificationEventArgs args)
{
StreamingSubscription subscription=args.Subscription;
if(subscription.Service.HttpHeaders.ContainsKey("X-AnchorMailBox"))
{
Console.WriteLine("event for nailbox"+subscription.Service.HttpHeaders["X-AnchorMailBox"]);
}
//loop through all the item-related events.
foreach(NotificationEvent notification in args.Events)
{
switch(notification.EventType)
{
case EventType.NewMail:
Console.WriteLine("\n----------------Mail Received-----");
break;
case EventType.Created:
Console.WriteLine("\n-------------Item or Folder deleted-------");
break;
case EventType.Deleted:
Console.WriteLine("\n------------Item or folder deleted---------");
break;
}
//Display notification identifier
if(notification is ItemEvent)
{
//The NotificationEvent for an email message is an ItemEvent
ItemEvent itemEvent=(ItemEvent)notification;
Console.WriteLine("\nItemId:"+ itemEvent.ItemId.UniqueId);
Item NewItem=Item.Bind(subscription.Service,itemEvent.ItemId);
if(NewItem is EmailMessage)
{
Console.WriteLine(NewItem.Subject);
}
}
else
{
//the Notification for a Folder is an FolderEvent
FolderEvent folderEvent=(FolderEvent)notification;
Console.WriteLine("\nFolderId:"+folderEvent.FolderId.UniqueId);
}
}
}
static void OnError(object sender,SubscriptionErrorEventArgs args)
{
//Handle error conditions.
Exception e=args.Exception;
Console.WriteLine("\n-----Error-----"+e.Message+"--------");
}
}
}
Here is an example :
_BackroundSyncThread = new Thread(streamNotification.SynchronizeChangesPeriodically); _BackroundSyncThread.Start();
private void SynchronizeChangesPeriodically()
{
while (true)
{
try
{
// Get all changes from the server and process them according to the business
// rules.
SynchronizeChanges(new FolderId(WellKnownFolderName.Calendar));
}
catch (Exception ex)
{
Console.WriteLine("Failed to synchronize items. Error: {0}", ex);
}
// Since the SyncFolderItems operation is a
// rather expensive operation, only do this every 10 minutes
Thread.Sleep(TimeSpan.FromMinutes(10));
}
}
public void SynchronizeChanges(FolderId folderId)
{
bool moreChangesAvailable;
do
{
Debug.WriteLine("Synchronizing changes...");
// Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
// Only the the ids are requested. Additional properties should be fetched via GetItem calls.
var changes = _ExchangeService.SyncFolderItems(folderId, PropertySet.FirstClassProperties, null, 512,
SyncFolderItemsScope.NormalItems, _SynchronizationState);
// Update the synchronization cookie
_SynchronizationState = changes.SyncState;
// Process all changes
foreach (var itemChange in changes)
{
// This example just prints the ChangeType and ItemId to the console
// LOB application would apply business rules to each item.
Console.WriteLine("ChangeType = {0}", itemChange.ChangeType);
Console.WriteLine("Subject = {0}", itemChange.Item.Subject);
}
// If more changes are available, issue additional SyncFolderItems requests.
moreChangesAvailable = changes.MoreChangesAvailable;
} while (moreChangesAvailable);
}
The _SynchronizationState field is like a Cookie that contains some informations about your last sync process . So next time the thread will synchronize all the items since the last sync .
Hope it helps

Is it possible to refactor this EventWaitHandle to not use Thread.Sleep() to control the race condition?

I want to send a message from a server to all clients. There are 0-* clients. The server may or may not be running when a client is loaded. The functionality here works how I want it. I am trying to figure out if this can be done without Thread.Sleep()? Also note that the clients and the server are each in independant processes.
Server Portion
class NamedEventsServer
{
internal static void Main()
{
const string ewhName = "StickyNoteEwh";
EventWaitHandle ewh = null;
bool doesNotExist = false;
bool wasCreated;
// Attempt to open the named event.
try
{
ewh = EventWaitHandle.OpenExisting(ewhName);
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("Named event does not exist.");
doesNotExist = true;
}
if (doesNotExist)
{
// The event does not exist, so create it.
ewh = new EventWaitHandle(true,
EventResetMode.ManualReset,
ewhName,
out wasCreated);
if (wasCreated)
{
Console.WriteLine("Created the named event.");
}
else
{
Console.WriteLine("Unable to create the event.");
return;
}
}
ewh.Set();
Thread.Sleep(1000);//wait one second...giving threads enough time to all respond. Then stop triggering the event.
ewh.Reset();
//exit
}
}
Client Portion
class NamedEventsClient
{
internal static void Main()
{
const string ewhName = "StickyNoteEwh";
while (true)
{
EventWaitHandle ewh = null;
bool doesNotExist = false;
bool wasCreated;
// Attempt to open the named event.
try
{
ewh = EventWaitHandle.OpenExisting(ewhName);
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("Named event does not exist.");
doesNotExist = true;
}
if (doesNotExist)
{
// The event does not exist, so create it.
ewh = new EventWaitHandle(false,
EventResetMode.ManualReset,
ewhName,
out wasCreated);
if (wasCreated)
{
Console.WriteLine("Created the named event.");
}
else
{
Console.WriteLine("Unable to create the event.");
return;
}
}
Console.WriteLine("Wait on the event.");
ewh.WaitOne();
Console.WriteLine("Event was signaled.");
//Console.WriteLine("Press the Enter key exit.");
Thread.Sleep(1000);
//Console.ReadLine();
}
}
}
I guess it depends whether you're certain all clients are going to get their time-slice within on second. It sounds reasonable, but under extreme stress some clients might miss it. How crucial is that?
Anyway, I think this is exactly the kind of thing you should use ZeroMQ for. It's light-weight, and takes care of all the potential bugs for you.

Categories