The last few days I have been working on updating a UI control from another thread and I thought I had it down with the Progress<> object.
Im running into a little issue with my Streamsocket TCP server project. I have everything up and running but I can't seem to figure out how to pass my data string back to my main UI.
Here is the jest of my program (when the client connects fire the event handler)
StreamSocketListener server = new StreamSocketListener();
server.ConnectionReceived += ClientConnection;
private async void ClientConnection(StreamSocketListener Client, StreamSocketListenerConnectionReceivedEventArgs args)
{
while (true)
{
The issue is i cant pass the ClientConnection Event Handler my Progress<> object.
I have spent the last few days trying to figure out another way to do it but nothing seems to work. Anyone have any ideas? I would really appreciate it.
Your code snipplet is incomplete.
Usually you follow the MVVM pattern - then the update of the control is done outside your code via NotifyPropertyChanged on the binded variable.
Related
I am beginner in c# with a huge problem.
An application with datagridview in front (Termin plan for one work day) works on many PC's in LAN with MS Windows Server and with MySQL database.
How can I become the changes made on one workstation AUTOMATICALY on all other PC's WITHOUT any action on them (application only started).
I have a procedure for data and datagridview refresh, I must only know WHEN I must start this procedure, that means I must know WHEN any other workstation made any changes.
Thanks for any help!
A simple solution would be to use a timer and when it elapses you refresh you gridview. so on defined period of time it will be refreshed automatically. the problem can be that if you update to often there's a overload of accessing the db. to prevent this, you could make an serverapplication which handles all data
Let's say PC 1 is starting the client application.
First it connects to server application (the server stores the reference of the client e.g. in an list).
After that the user on PC1 makes changes and click on save, the software will send the changes to the server (e.g. a custom object with all needed information).
Server saves the changes to the DB
Serverapplication give a response to the specific client if it worked or not
If it worked, Send an custom object (for example named ChangesDoneEvent) to all clients that indicates that changes have been done.
All connected clients will receive that object and know now that the have to refresh their gridview.
For further information just search for C# Multi threaded Server Socket programming. For sending custom objects over network you will find many resources in the internet too, maybe this will help you Sending and receiving custom objects using Tcpclient class in C#
Declare Delegate on your form
public delegate void autocheck();
private System.Timers.Timer TTTimer = new System.Timers.Timer();
public void autofilldgv()
{
if (this.InvokeRequired)
{
this.Invoke(new autocheck(UpdateControls));
}
else
{
UpdateControls();
}
}
private void UpdateControls()
{
//call your method here
filldgv();
}
void TTTimer_Elapsed(object sender System.Timers.ElapsedEventArgs e)
{
mymethod();
}
public void mymethod()
{
//this method is executed by the background worker
autofilldgv();
}
private void frm_receptionView_Load(object sender, EventArgs e)
{
this.TTTimer.Interval = 1000; //1 sec interval
this.TTTimer.Elapsed += new System.Timers.ElapsedEventHandler(TTTimer_Elapsed);
this.TTTimer.Start();
}
The solution provided above is actually a good way to handle this scenario. Before implementing you might also want to think about the potential fall backs. It is possible that Client PC 's IP could change and since you are using sockets. The object reference added in the list could be faulted state. You might want to think of handling this pitfall.
I develop an application on windowCE 5.0 with opennetcf library.
I want to check WHEN my Device is connected to Cradle. It means I want to handle the event of plugged the device to cradle or other similar.
My purpose is that when Device is connected to Cradle, I disable all forms of my application,
and when it is removed from cradle, all the forms are enabled.
I search much. But the answer is not matched to my expect.
Please help me.
After reading reference of opennetcf, I found out the two events: ACPowerApplied and ACPowerRemoved
Here is my code:
public static event DeviceNotification ACPowerApplied;
public static event DeviceNotification ACPowerRemoved;
void Form1_ACPowerRemoved()
{
MessageBox.Show("Un-cradle");
}
void Form1_ACPowerApplied()
{
MessageBox.Show("Cradle");
}
private void Form1_Load(object sender, EventArgs e)
{
ACPowerApplied += new DeviceNotification(Form1_ACPowerApplied);
ACPowerRemoved += new DeviceNotification(Form1_ACPowerRemoved);
}
But the process did not step into Form1_ACPowerRemoved() and Form1_ACPowerApplied().
Is there any idea for that? Sorry for my poor English. Thank you in advance.
Your code is wrong. You've subscribed to the form's event, and nobody raise it.
Documentation doesn't show how-to-use code, I think. It shows declaraion.
Maybe it will work (not tested):
OpenNETCF.WindowsCE.DeviceManagement.ACPowerApplied += Form1_ACPowerApplied
OpenNETCF.WindowsCE.DeviceManagement.ACPowerRemoved += Form1_ACPowerRemoved
Also you can try to use WinAPI calls: http://blogs.msdn.com/b/davidklinems/archive/2005/02/10/370591.aspx
If you want, I have complete code, but there are a lot of waste and "OnRs232Connect" event.
By the way, what does "craddled" mean for you? Craddle can be disconneted from both AC and PC. I mean, do you want to handle when your device started to get electricity power, or when it started connecting to the PC via Active Sync? If the second, you want to catch "OnRs232Connect" event
I'm new with C# so go easy on me!
So far - I have a console app that listens for client connections and replies to the client accordingly.
I also have a WPF form with a button and a text box. The button launches some code to connect to the server as a BackgroundWorker, which then waits for a response before appending it to the end of the text box.
This works great, once. Sometimes twice. But then it kept crashing - turns out that the DoWork block wasn't being called at all and it was going straight to RunWorkerCompleted. Of course, the .result is blank so trying to convert it to a string fails.
Is this a rookie mistake? I have tried searching the internet for various ways of saying the above but haven't come across anything useful...
This is the code so far: http://pastebin.com/ZQvCFqxN - there are so many debug outputs from me trying to figure out exactly what went wrong.
This is the result of the debug outputs: http://pastebin.com/V412mppX
Any help much appreciated. Thanks!
EDIT: The relevant code post-fix (thanks to Patrick Quirk below) is:
public void dorequest(string query)
{
request = new BackgroundWorker();
request.WorkerSupportsCancellation = true;
request.WorkerReportsProgress = true;
request.ProgressChanged += request_ProgressChanged;
request.DoWork += request_DoWork;
request.RunWorkerCompleted += request_RunWorkerCompleted;
request.RunWorkerAsync(query);
}
You're attaching your DoWork handler after calling RunWorkerAsync. Flip those around and that should fix it.
Also, in the future please paste code in your question rather than using an external site. And when possible give the smallest amount of code that demonstrates the problem. Makes it easier on us and people who might have the same issue.
I working on an application handling serial port communication. It's a WPF, multithreaded application. Everything went fine until I sent only small packages through the COM port with communication.
No I reached a phase, where I have to listen for data sent to my application on COM port. For this big chunk of data I go into trouble. I have only one DataReceived event fired, which reads part of the data I need. But after that there is no DataReceived event fired anymore for the rest of the data.
If I monitor the COM port I saw that the bytes are there, the monitoring software states, that there are 2067 bytes in the in queue, but the event do not fire.
I searched Google for similar problems, but I was unable to find relevant answers for this. Have you got any idea where to start searching the roots of the problem.
Thanks in advance.
Here is the code of the DataReceived handler:
private void comPort_DataReceived( object sender, SerialDataReceivedEventArgs e )
{
do
{
new Thread(() =>
{
OnReceivingData(new ComPortCommunicationEventArgs(DataTransferDirections.Receiving, DataTransferActions.Start));
}).Start();
byte[] packetData = null;
try
{
IsReceiving = true;
int bytesToReadCount = comPort.BytesToRead;
if ( bytesToReadCount == 0 )
{
return;
}
packetData = new byte[bytesToReadCount];
comPort.Read(packetData, 0, bytesToReadCount);
}
finally
{
IsReceiving = false;
new Thread(() =>
{
OnReceivingData(new ComPortCommunicationEventArgs(DataTransferDirections.Receiving, DataTransferActions.End));
}).Start();
}
OnPacketReceived(new PacketReceivedEventArgs(comPort.PortName, packetData.ToList()));
} while ( comPort.BytesToRead > 0 );
}
What I found out meanwhile, that if I comment out the OnPacketReceived call - which just fires event for the UI with the received data - than the data processing works fine. So it's not a COM port communication error I think...
Update:
I found the solution for my problem. It was not related to serial port handling.
In one of my data processing threads I run into a loop, which was supposed to be finished on succesfull processing, but with not enough data it was just run continously. Doing that it was blocked the DataReceived event handler - which is still not fully clear for my why, since the two process should be on diffrerent threads I supposed. But it seems that I'm wrong with this.
Anyway I corrected the processing method, and no I receive the data from the serisl port.
Sorry to take your time, and thanks for your help anyway your ideas helped my localize this problem.
Br,
Csaba
I worked with COM ports 5 years ago, and I know how tricky it can get sometimes. All sorts of tricky problems happened with the Siemens device I used to work with :)
First off, I couldn't follow your code thoroughly, so I can't know for sure if your DataReceived routine is sane. I suggest you try to replace all that code inside comPort_DataReceived to something very simple, only for test purposes.
private static void comPort_DataReceived(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
If it still doesn't work, then the problem is not in your code. If you don't know what else to try, I would mess with parameters such as SerialPort.DtrEnable and SerialPort.RtsEnable and see if something happens, because these also caused some not-in-the-manual bugs for me in the past.
Piece of code extracted from MSDN.
I'm having some serious troubles getting communication from one thread to another working between NetworkStream.BeginRead() and a WinForms class (I'm a real newbie when it comes to topics such as threading and Asynchronous calls).
In particular, I'm connected to a remote client via a net socket, simply listening for events. When I receive one, I can correctly collect it into a string using the BeginRead() and EndRead() methods of NetworkStream, no problems. I intend to then open up a new form (using the string as a parameter in the form's constructor) so that the information can be displayed to the user. Effectively, the network event will trigger a form for the user to be opened, and the information However, I'm constantly coming across CrossThreadMessagingExceptions, and I'm not familiar enough with delegates that I'm convinced I'm doing it right. Would someone be able to point me in the right direction?
The rule is: "You can only access controls on the thread on which they created"
You async callbacks are coming back on a different thread, so you need to marshal back to the UI thread if you want to communicate between forms.
Assuming you're NetworkStream code is already in a form, you just need to use Invoke or BeginInvoke. For example:
private void MyAsyncCallback(IAsyncResult ar)
{
var yourString = ...from your socket...;
this.Invoke(new MethodInvoker(() => new Form(yourString)));
}