I've created windows application which uses an remote online MYSQL database.For connection i've created a DataConnector() Class. Everytime when i want to connect I create an object of DataConnector() class.
Actually I want to show the progressbar during the connection takes place to database, i mean the progressbar should be on the top of application, after connection successful the progressbar should close automatically.
need some idea how to do it...I've tried with "backgroundworker" but facing prob as the function inside the class returns "MySqlConnection" type.
Here is my DataConnector() Class..
namespace omg
{
class DataConnector
{
bool connected = false;
MySqlConnection connection = null;
MySqlCommand command;
string connectionstring = "server=127.0.0.1;database=online_trading_system;UserId=root;Password=phanny";
public MySqlConnection connect()
{
try
{
connection = new MySqlConnection(connectionstring);
connection.Open();
connected = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return connection;
}
MessageBox.Show("connected with the databse");
// connection.Close();
//connected = false;
return connection;
}
public void close()
{
connection.Close();
connected = false;
MessageBox.Show("connection Closed");
}
}
}
Your BackgroundWorker approach was correct. Here's a short sample:
private void OpenConnectionButton_Click() {
var bw = new BackgroundWorker();
bw.DoWork += (sender, e) => {
// this will happen in a separate thread
var connector = new DataConnector();
connector.connect(); // this might take a while
e.Result = connector;
}
bw.RunWorkerCompleted += (sender, e) => {
// We are back in the UI thread here.
// close the progress bar
...
if (e.Error != null) // if an exception occurred during DoWork,
MessageBox.Show(e.Error.ToString()); // do your error handling here
else {
var connector = (DataConnector)e.Result;
// do something with your connector
}
};
// show the progress bar
...
bw.RunWorkerAsync(); // start the background worker
}
Related
I need your help. I'm trying to implement SqlDependency in a console app to constantly monitor a database table (ultimately a service broker queue). Here is my code and the problem is that after one execution application exits.
class Program
{
static void Main(string[] args)
{
var listener = new Listener();
listener.Listening();
Console.ReadKey();
}
}
public class Listener
{
const string notificationQuery = "SELECT [ID],[Name] FROM [dbo].[tblUsers]";
const string sampleConnectionString = #"Server = xxx; Database = yyy; Integrated Security = SSPI;";
public void Listening()
{
try
{
SqlClientPermission permission = new SqlClientPermission(PermissionState.Unrestricted);
permission.Demand();
}
catch (Exception ex)
{
}
using (var connection = new SqlConnection(sampleConnectionString))
{
connection.Open();
using (var command = new SqlCommand(notificationQuery, connection))
{
SqlDependency.Start(sampleConnectionString);
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
var hasChanges = dependency.HasChanges;
command.ExecuteReader();
}
}
}
void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
Console.WriteLine(sender);
Listening();
}
What I found:
how to keep sql dependency doing the its purpose
but adding Listening(); to EventHandler doesn't help. When I'm debugging program and I add some value to the table event is triggered but this adds only one more execution of the Listening method while I want the app to keep working and monitoring the table all the time. Can someone help?
I'm creating a game in which I use TCP/IP connection. The problem is that I'm using .Invoke to help me receive and send message.
The program goes like this: I'm my first window, i'm starting and connecting to the server like this :
{
TcpListener listener = new TcpListener(IPAddress.Any, this.port);
listener.Start();
try {
this.client = listener.AcceptTcpClient();
gameWindow = new GameWindow(this.client, true);
gameWindow.StartGame();
}
}
then i'm connecting to it like this:
{
IPEndPoint ipEnd = new IPEndPoint(this.serverIP, this.port);
{
try {
client.Connect(ipEnd);
if (client.Connected) {
gameWindow = new GameWindow(this.client, false);
gameWindow.StartGame();
}
}
}
The constructor for gameWindow (which is a form) looks like this:
public GameWindow(TcpClient thisClient, bool isServer)
{
InitializeComponent();
this.client = thisClient;
this.reader = new StreamReader(thisClient.GetStream());
this.writer = new StreamWriter(thisClient.GetStream());
this.writer.AutoFlush = true;
}
I must wait for the server to send a message to the client, and then start the client ( I have a function .startGame() that uses .ShowDialog() and creates some pictureBoxs)
But nowhere I can get my handle created. I've tried to put this.createHandle() (read about it here) into GameWindow_Load but still not works. If I try to send a message with:
workerSendData.RunWorkerAsync(); I get:
Additional information: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
What can I do to get my handler created? Using Thread.Sleep will sleep my whole UI, which does not work (a "solution" found on the internet)
My code for sending message :
private void workerSendData_DoWork(object sender, DoWorkEventArgs e)
{
if (client.Connected) {
this.writer.WriteLine(this.toSend); // aici trimitem datele.
// de modificat : aici vom adauga in lista noastra miscarile.
this.Invoke(new MethodInvoker(delegate () { MessageBox.Show("Me:" + this.toSend + "\n"); }));
}
else {
MessageBox.Show("Send failed");
}
workerSendData.CancelAsync();
}
My code for receiving data:
private void workerReceiveData_DoWork(object sender, DoWorkEventArgs e)
{
while (client.Connected) {
try {
this.received = this.reader.ReadLine();
this.myTurn = true;
this.Invoke(new MethodInvoker(delegate () {
MessageBox.Show("This has been received: " + this.received);
/*this.tbReceive.AppendText("You:" + this.received + "\n");*/
}));
this.received = "";
}
catch (Exception x) {
MessageBox.Show(x.Message.ToString());
}
}
}
It seems that you cannot invoke an action before the Window is fully initialized and loaded. Assuming you are working in Windows Forms, there is a solution provided by #Greg D on this question, but it doesn't be to be the safest way to go.
I would suggest that you try to find a way to start the worker only after the window is loaded (for example using the Loaded event), so that the handle is definitely ready and this situation does not occur.
i do have an embedded board (mini/tiny 210)
and i did try building an application which uses system.socket and system.socket.net in C# ( vs2005 - wince5 device application but i do have wince 6 on my device!! )
my purpose is to send and receive data bytes using Ethernet. for sending , well there is no problem but receive does need multitasking.
i should start a task so it can listen to the port if there is any data upcoming but once i add thread part to my code the whole program crashes (dose not do that in pc x64 core i5) but in embedded board it will crash.
if i eliminate multi tasking i might lose some data when networkstream.read is not online or when networkstream.read is online and i'm waiting for data,which ends in program will not respond up until the timeout. here is some of my codes . hope it helps.
this code does work :
private void button_connect_Click(object sender, EventArgs e)
{
try
{
//Thread TH = new Thread(new ThreadStart(con));
//TH.Start();
con();
}
catch
{
MessageBox.Show("THREAD ERROR");
}
}
public void con()
{
try
{
cli = null;
cli = new TcpClient();
cli.Connect(IPAddress.Parse(textBox_ip.Text),Convert.ToInt32(textBox_port.Text));
st = null;
st = cli.GetStream();
button_connect.Enabled = false;
button_Close.Enabled = false;
button_disconnect.Enabled = true;
statusBar1.Text = "Connected to server";
//Thread rec = new Thread(new ThreadStart(recf));
//rec.Start();
}
catch
{
MessageBox.Show("Connection faild","Error");
statusBar1.Text = "Faild to connect to server";
}
this code dose not work :
private void button_connect_Click(object sender, EventArgs e)
{
try
{
Thread TH = new Thread(new ThreadStart(con));
TH.Start();
//con();
}
catch
{
MessageBox.Show("THREAD ERROR");
}
}
public void con()
{
try
{
cli = null;
cli = new TcpClient();
cli.Connect(IPAddress.Parse(textBox_ip.Text),Convert.ToInt32(textBox_port.Text));
st = null;
st = cli.GetStream();
button_connect.Enabled = false;
button_Close.Enabled = false;
button_disconnect.Enabled = true;
statusBar1.Text = "Connected to server";
//Thread rec = new Thread(new ThreadStart(recf));
//rec.Start();
}
catch
{
MessageBox.Show("Connection faild","Error");
statusBar1.Text = "Faild to connect to server";
}
}
as you can see i'm getting this crash while just one of my task is in the code the second task has been commented
i appreciate your help in advance
The crash is probably caused by updating UI elements from a secondary thread.
The con method reads a textbox and updates several buttons as well as a status bar, and this should only happen on the main application thread.
To verify whether this is the issue, you could simply comment out the lines in the con method that access UI elements (copy the textbox value to a member string before starting the thread, or just hard-code the IP address) and re-run the application.
Then to actually fix the problem you'll have to look into Control.Invoke.
I created a Sql server database, in which I added a table named user. Then I executed this script
ALTER DATABASE [TestNotification] SET ENABLE_BROKER
I'd like to use SqlDependency class to notify a winforms application when the user table were changed.
namespace Watcher
{
public partial class Form1 : Form
{
private int changeCount = 0;
private const string statusMessage = "{0} changes have occurred.";
private DataSet dataToWatch = null;
private SqlConnection connection = null;
private SqlCommand command = null;
public Form1()
{
InitializeComponent();
button1.Enabled = CanRequestNotifications();
this.FormClosed += Form1_FormClosed;
}
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
SqlDependency.Stop(GetConnectionString());
if (connection != null)
{
connection.Close();
}
}
private bool CanRequestNotifications()
{
// In order to use the callback feature of the
// SqlDependency, the application must have
// the SqlClientPermission permission.
try
{
SqlClientPermission perm =
new SqlClientPermission(
PermissionState.Unrestricted);
perm.Demand();
return true;
}
catch
{
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
changeCount = 0;
label1.Text = String.Format(statusMessage, changeCount);
//SqlDependency.Stop(GetConnectionString());
SqlDependency.Start(GetConnectionString());
if (connection == null)
{
connection = new SqlConnection(GetConnectionString());
}
if (command == null)
{
command = new SqlCommand(GetSQL(), connection);
}
if (dataToWatch == null)
{
dataToWatch = new DataSet();
}
GetData();
}
private string GetConnectionString()
{
return #"Data Source=BILOG-PRT-12\SQLEXPRESS; Initial Catalog=TestNotification;Integrated Security=True";
}
private string GetSQL()
{
return "Select [id],[nom],[prenom],[age] from [dbo].[user]";
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
MessageBox.Show("modification Occurred");
ISynchronizeInvoke i = (ISynchronizeInvoke)this;
if (i.InvokeRequired)
{
OnChangeEventHandler tempDelegate =new OnChangeEventHandler(dependency_OnChange);
object[] args = { sender, e };
i.BeginInvoke(tempDelegate, args);
return;
}
SqlDependency dependency = (SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
++changeCount;
label1.Text = String.Format(statusMessage, changeCount);
GetData();
}
private void GetData()
{
//dataToWatch.Clear();
//command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
if (connection.State != ConnectionState.Open) connection.Open();
using (var dr = command.ExecuteReader())
{
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
}
}
}
}
All the broker service are running :
I launched the application, Then I clicked into the button and finally I go the Sql Server management studio And I inserted a new row. The problem is that the message box in the application is not shown so the c# application is not notified by SQL Server!!!
So I need to know :
Why this happens?
Which step I forget ?
How can I resolve this issue?
There's quite a few limitations with SqlDependency. To quote one relevant issue:
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names.Notice that this means that all tables referenced in the statement must be in the same database.
(see https://msdn.microsoft.com/library/ms181122.aspx for the full list)
You have to explicitly use two-part name (e.g. dbo.user instead of just user).
Also, you need to execute the command. It doesn't just start working automagically :) Adding a simple using (var dr = command.ExecuteReader()) {} should be enough.
I have a test web connection form in c#. I want to show a loading window while my connection is being checked, and then show the result of checking.
This is my code for testing the web connection:
public bool ConnectionAvailable(string strServer)
{
try
{
HttpWebRequest reqFP = (HttpWebRequest)HttpWebRequest.Create(strServer);
HttpWebResponse rspFP = (HttpWebResponse)reqFP.GetResponse();
if (HttpStatusCode.OK == rspFP.StatusCode)
{
// HTTP = 200 - Internet connection available, server online
rspFP.Close();
return true;
}
else
{
// Other status - Server or connection not available
rspFP.Close();
return false;
}
}
catch (WebException)
{
// Exception - connection not available
return false;
}
}
And this:
private void button1_Click(object sender, EventArgs e)
{
string url = "Web-url";
label1.Text = "Checking ...";
button1.Enabled = false;
if (ConnectionAvailable(url))
{
WebClient w = new WebClient();
w.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
label1.Text = w.UploadString(url, "post", "SN=" + textBox1.Text);
button1.Enabled = true;
}
else
{
label1.Text = "Conntion fail";
button1.Enabled = true;
}
}
On a windows forms application the user interface runs on one thread, if you try to run a long running process, which checking the web connection might end up being this will cause the form to freeze until it completes the work.
So, I'd start a new thread that does the check. then raise an event to return the result. while all that's happening you can do what you like with the user interface, such as a loading graphic, or even allow the user to continue using features that don't require the internet connection.
Create EventArgs class of your own so you can pass back the result:
public class ConnectionResultEventArgs : EventArgs
{
public bool Available { get; set; }
}
Then in your form class, create your event, handlers and the method to action when the event arrives
//Create Event and Handler
public delegate void ConnectionResultEventHandler(object sender, ConnectionResultEventArgs e);
public event ConnectionResultEventHandler ConnectionResultEvent;
//Method to run when the event has been receieved, include a delegate in case you try to interact with the UI thread
delegate void ConnectionResultDelegate(object sender, ConnectionResultEventArgs e);
void ConnectionResultReceived(object sender, ConnectionResultEventArgs e)
{
//Check if the request has come from a seperate thread, if so this will raise an exception unless you invoke.
if (InvokeRequired)
{
BeginInvoke(new ConnectionResultDelegate(ConnectionResultReceived), new object[] { this, e });
return;
}
//Do Stuff
if (e.Available)
{
label1.Text = "Connection Good!";
return;
}
label1.Text = "Connection Bad";
}
Subscribe to the event when your form loads:
private void Form1_Load(object sender, EventArgs e)
{
//Subscribe to the the results event.
ConnectionResultEvent += ConnectionResultReceived;
}
and then setup the worker thread:
//Check the connection
void BeginCheck()
{
try
{
HttpWebRequest reqFP = (HttpWebRequest)HttpWebRequest.Create("http://google.co.uk");
HttpWebResponse rspFP = (HttpWebResponse)reqFP.GetResponse();
if (HttpStatusCode.OK == rspFP.StatusCode)
{
// HTTP = 200 - Internet connection available, server online
rspFP.Close();
ConnectionResultEvent(this, new ConnectionResultEventArgs {Available = true});
}
else
{
// Other status - Server or connection not available
rspFP.Close();
ConnectionResultEvent(this, new ConnectionResultEventArgs { Available = false });
}
}
catch (WebException)
{
// Exception - connection not available
//Raise the Event - Connection False
ConnectionResultEvent(this, new ConnectionResultEventArgs { Available = false });
}
}
private void button1_Click(object sender, EventArgs e)
{
//loading graphic, screen or whatever
label1.Text = "Checking Connection...";
//Begin the checks - Start this in a new thread
Thread t = new Thread(BeginCheck);
t.Start();
}
I am thinking of threading! One thread checks the connection while the other one is showing the loading window. If for example the connection has been established you can notify the other thread and show the result.