C# Stops Executing When Opening A Connection To MySql - c#

I am writing an application to transfer data from a simulated OPC server to a MySql Database. I am using some of the libraries from OPC Foundation - OPCNETAPI.DLL, OPCNETAPI.COM.DLL.
I have the program reading from the server happily, but it seems as soon as I open a connection inside the loop of reading data, it loops about 5 times and then stops executing.. There are no exceptions thrown and I have tried for hours to work it out and miserably failed.
I've also changed VisualStudio to break when an exception is thrown, and it doesn't
Hopefully some one may know whats going on, but there is nothing obvious, hopefully the following code will spark ideas!
Windows Forms Code
public void readplc()
{
Opc.URL url = new Opc.URL("opcda://localhost/Matrikon.OPC.Simulation.1");
Opc.Da.Server server = null;
OpcCom.Factory fact = new OpcCom.Factory();
server = new Opc.Da.Server(fact, null);
try
{
server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));
}
catch (Exception ecy)
{
}
// Create a group
Opc.Da.Subscription group;
Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();
groupState.Name = "Group";
groupState.Active = true;
group = (Opc.Da.Subscription)server.CreateSubscription(groupState);
// add items to the group.
Opc.Da.Item[] items = new Opc.Da.Item[2];
items[0] = new Opc.Da.Item();
items[0].ItemName = "Random.Int1";
items[1] = new Opc.Da.Item();
items[1].ItemName = "Random.Time";
items = group.AddItems(items);
group.DataChanged += new Opc.Da.DataChangedEventHandler(OnTransactionCompleted);
}
public void OnTransactionCompleted(object group, object hReq, Opc.Da.ItemValueResult[] items)
{
for (int i = 0; i < items.GetLength(0); i++)
{
try
{
string a = items[i].Value.ToString();
string b = items[i].ItemName;
string c = items[i].Key;
MySqlConnection conn = new MySqlConnection("server=localhost;user id=localhost;password=localhost;database=localhost;pooling=false");
conn.Open();
conn.Close();
}
catch (Exception ec)
{
MessageBox.Show(ec.Message);
}
}
}
I have set break points throughout the code, stepped through everything possible and still nothing obvious that's causing the issue.

Related

TF20507: The string argument contains a character that is not valid:'u0009'. Correct the argument, and then try the operation again

I started getting this error when calling ReadIdentities... After updating from Visual studio 2010 to 2012 SDK. It crashes due to invalid "\t" in one of the members. (New validation rules in TFS API probably).
var GSS = tfs.GetService<IIdentityManagementService>();
Identity SIDS = project.GSS.ReadIdentity(SearchFactor.AccountName, "Project Collection Valid Members", QueryMembership.Expanded);
var _TFSUsers = project.GSS.ReadIdentities(SearchFactor.Sid, SIDS.Members, QueryMembership.None);
The saddest part of this story is that I need to find out which member has this tab char. And TFS contains 2000+ members. I tried running one by one, but only ReadIdentities method crashes. ReadIdentity passes. So decided to follow these steps:
foreach (var memberSID in SIDS.Members)
{
try
{
var identity = project.GSS.ReadIdentities(SearchFactor.Sid,new string[] { memberSID,}, QueryMembership.None);
}
catch (Exception ex2)
{
throw new InvalidOperationException("Failed to load TFS user: " + memberSID, ex2);
}
}
Yet somehow this did not work either! As the code ran flawlessly with no exceptions.
I have produced the method which splits the array half and tries to narrow the search until the smallest possible size.
private static void SplitHalf(string[] identities, IIdentityManagementService GSS)
{
var count = identities.Count();
int half = count / 2;
List<string> half1 = new List<string>();
List<string> half2 = new List<string>();
for (int i = 0; i < half; i++)
{
half1.Add(identities[i]);
}
var halfArray1 = half1.ToArray();
try
{
var users = GSS.ReadIdentities(SearchFactor.Sid, halfArray1, QueryMembership.None);
}
catch (Exception ex)
{
SplitHalf(halfArray1, GSS);
}
for (int i = half; i < count; i++)
{
half2.Add(identities[i]);
}
var halfArray2 = half2.ToArray();
try
{
var users = GSS.ReadIdentities(SearchFactor.Sid, halfArray2, QueryMembership.None);
}
catch (Exception ex)
{
SplitHalf(halfArray2, GSS);
}
}
This way, I was able to put breakpoint with condition count == 2. And narrowed down to find out the display name and identity that was crashing the stuff. I hope this saves some time for someone. It appears that crashing occurs only when minimum of two SIDS are supplied for the method parameters, supplying only one, did not result in error...

Why would this query generate a file sharing violation?

The following code gives me the error (I get it from the MessageBox.Show() in the catch block)
"Exception in PopulateBla() : There is a file sharing violation. A
different process might be using the file [,,,,,,]
CODE
using (SqlCeCommand cmd = new SqlCeCommand(SQL_GET_VENDOR_ITEMS, new SqlCeConnection(SQLCE_CONN_STR)))
{
cmd.Parameters.Add("#VendorID", SqlDbType.NVarChar, 10).Value = vendorId;
cmd.Parameters.Add("#VendorItemID", SqlDbType.NVarChar, 19).Value = vendorItemId;
try
{
cmd.Connection.Open();
using (SqlCeDataReader SQLCEReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (SQLCEReader.Read())
{
itemID = SQLCEReader.GetString(ITEMID_INDEX);
packSize = SQLCEReader.GetString(PACKSIZE_INDEX);
recordFound = true;
}
}
}
catch (SqlCeException err)
{
MessageBox.Show(string.Format("Exception in PopulateControlsIfVendorItemsFound: {0}\r\n", err.Message));//TODO: Remove
}
finally
{
if (cmd.Connection.State == ConnectionState.Open)
{
cmd.Connection.Close();
}
}
}
SQL_GET_VENDOR_ITEMS is my query string.
What file sharing problem could be happening here?
UPDATE
This is the kind of code that makes that sort of refactoring recommended by ctacke below difficult:
public void setINVQueryItemGroup( string ID )
{
try
{
dynSQL += " INNER JOIN td_item_group ON t_inv.id = td_item_group.id AND t_inv.pack_size = td_item_group.pack_size WHERE td_item_group.item_group_id = '" + ID + "'";
}
catch( Exception ex )
{
CCR.ExceptionHandler( ex, "InvFile.setINVQueryDept" );
}
}
A SQL statement is being appended to by means of a separate method, altering a global var (dynSQL) while possibly allowing for SQL Injection (depending on where/how ID is assigned). If that's not enough, any exception thrown could mislead the weary bughunter due to indicating it occurred in a different method (doubtless the victim of a careless copy-and-paste operation).
This is "Coding Horror"-worthy. How many best practices can you ignore in a scant few lines of code?
Here's another example:
string dynSQL = "SELECT * FROM purgatory WHERE vendor_item = '" + VendorItem + "' ";
if (vendor_id != "")
{
dynSQL += "AND vendor_id = '" + vendor_id + "' ";
}
It could be done by replacing the args with "?"s, but the code to then determine which/how many params to assign would be 42X uglier than Joe Garagiola's mean cleats.
I really like Chris' idea of using a single connection to your database. You could declare that global to your class like so:
public ClayShannonDatabaseClass
{
private SqlCeConnection m_openConnection;
public ClayShannonDatabaseClass()
{
m_openConnection = new SqlCeConnection();
m_openConnection.Open();
}
public void Dispose()
{
m_openConnection.Close();
m_openConnection.Dispose();
m_openConnection = null;
}
}
I'm guessing your code is crashing whenever you attempt to actually open the database.
To verify this, you could stick an integer value in the code to help you debug.
Example:
int debugStep = 0;
try
{
//cmd.Connection.Open(); (don't call this if you use m_openConnection)
debugStep = 1;
using (SqlCeDataReader SQLCEReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
debugStep = 2;
if (SQLCEReader.Read())
{
debugStep = 3;
itemID = SQLCEReader.GetString(ITEMID_INDEX);
debugStep = 4;
packSize = SQLCEReader.GetString(PACKSIZE_INDEX);
debugStep = 5;
recordFound = true;
}
}
}
catch (SqlCeException err)
{
string msg = string.Format("Exception in PopulateControlsIfVendorItemsFound: {0}\r\n", err.Message);
string ttl = string.Format("Debug Step: {0}", debugStep);
MessageBox.Show(msg, ttl); //TODO: Remove
}
// finally (don't call this if you use m_openConnection)
// {
// if (cmd.Connection.State == ConnectionState.Open)
// {
// cmd.Connection.Close();
// }
// }
I'm guessing your error is at Step 1.
Provided the file isn't marked read-only (you checked that, right?), then you have another process with a non-sharing lock on the file.
The isql.exe database browser that comes with SQL CE is a common culprit if it's running in the background.
Depending on your version of SQLCE, it's quite possible that another process has an open connection (can't recall what version started allowing multiple process connections), so if you have any other app in the background that has it open, that may be a problem too.
You're also using a boatload of connections to that database, and they don't always get cleaned up and released immediately up Dispose. I'd highly recommend building a simple connection manager class that keeps a single (or more like two) connections to the database and just reuses them for all operations.

File Watch Application fails when file saved by remote user

My problem is this, and before I annoy anybody, this is my first post so if I err, forgive me.
I have created a simple windows service with a file system watcher that triggers a console application if a .txt file is pasted. The service is running as Local System, and works perfectly. However, the files it watches for are saved every morning by a remote user, and the console application fails without cause. If I save the file, the service AND the console application do exactly what they are supposed to.
The console application uses the GeneticParsing Library to read the file into a table, bulk loads it into an oracle 11g db on a remote server, then archives the file. The main code for the console application is below... any help would be much appreciated!
static void Main(string[] args)
{
try
{
FileInfo f = new FileInfo(args[0].ToString());
Thread.Sleep(15000);
GenericParserAdapter p = new GenericParserAdapter();
p.ColumnDelimiter = '|';
p.SetDataSource(f.FullName);
DataTable d = new DataTable();
d = p.GetDataTable();
bb_usage_methods b = new bb_usage_methods(false);
DataTable d_merge = new DataTable();
d_merge.Columns.Add("BB_USAGE_ID", Type.GetType("System.Int32"));
d_merge.Columns.Add("USAGE_DATE", Type.GetType("System.DateTime"));
d_merge.Columns.Add("PARTY_CODE", Type.GetType("System.Int32"));
d_merge.Columns.Add("UPLOAD_USAGE", Type.GetType("System.Decimal"));
d_merge.Columns.Add("DOWNLOAD_USAGE", Type.GetType("System.Decimal"));
d_merge.Columns.Add("TOTAL_USAGE", Type.GetType("System.Decimal"));
DataRow r;
object j = b.get_data_from_datareader("SELECT MAX(BB_USAGE_ID) FROM USAGE");
Int32 max_id = j.ToString() == "Entry is NULL" || j.GetType() == System.Type.GetType("System.Exception") ? max_id = 1 : max_id = Convert.ToInt32(j) + 1;
for (int i = 0; i < d.Rows.Count; i++)
{
r = d.Rows[i];
try
{
object[] o = { max_id, Convert.ToDateTime(r[0]), Convert.ToDecimal(r[1]), Convert.ToDecimal(r[2]), Convert.ToDecimal(r[3]), Convert.ToDecimal(r[4]) };
d_merge.Rows.Add(o);
max_id++;
}
catch { }
r = null;
}
decimal original_count = Math.Round((decimal)(d.Rows.Count * 100) / d_merge.Rows.Count, 2);
b.bulk_insert_into_oracle(d_merge, "USAGE");
DateTime dt = f.LastWriteTime;
try
{
File.Move(f.FullName, f.FullName.Replace(f.Name, #"\..\Archive\" + f.Name));
}
catch (Exception e)
{
// code to log error to db
}
}
catch (Exception ex)
{
// code to log error to db
}
}
}
public class log_methods : x.oracle_data_access
{
public log_methods()
{
base.get_dataset("SELECT * FROM APP_LOG", "LOG_ID");
}
}
public class bb_usage_methods : x.oracle_data_access
{
public bb_usage_methods(Boolean get_dataset)
{
if (get_dataset)
{
base.get_dataset("SELECT * FROM USAGE", "BB_USAGE_ID");
}
}
}
Are you sure the filewatcher sees that file?
Is the program launched at all when remote user saves it.
If i remember right, there are some case where the filewatcher doesn't trigger when it should (in remote or whatnot).

System.DirectoryServices.Protocols Paged get all users code suddenly stopped getting more than the first page of users

So here is the code using S.DS.P to get all users very quickly in pages of 500 at a time..
public List<AllAdStudentsCV> GetUsersDistinguishedNamePagedResults( string domain, string distinguishedName )
{
try
{
NetworkCredential credentials = new NetworkCredential( ConfigurationManager.AppSettings["AD_User"], ConfigurationManager.AppSettings["AD_Pass"] );
LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier( domain + ":389" );
List<AllAdStudentsCV> users = new List<AllAdStudentsCV>();
using (LdapConnection connection = new LdapConnection(directoryIdentifier, credentials))
{
string filter = "(&(objectClass=user)(objectCategory=person))";
string baseDN = ConfigurationManager.AppSettings["AD_DistinguishedName"];
string[] attribArray = {"name", "sAMAccountName", "objectGUID", "telexNumber", "HomePhone"};
List<SearchResultEntry> srList = PerformPagedSearch(connection, baseDN, filter, attribArray);
if (srList.Count == 0) return null;
foreach (SearchResultEntry entry in srList)
{
<...snip a bunch of code to filter out bad users by CN...>
users.Add( user );
}
catch ( Exception ex )
{
throw;
}
}
}
}
return users;
}
catch ( Exception ex )
{
throw;
}
}
private List<SearchResultEntry> PerformPagedSearch( LdapConnection connection, string baseDN, string filter, string[] attribs )
{
List<SearchResultEntry> results = new List<SearchResultEntry>();
SearchRequest request = new SearchRequest(
baseDN,
filter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
attribs
);
PageResultRequestControl prc = new PageResultRequestControl(500);
//add the paging control
request.Controls.Add(prc);
int pages = 0;
while (true)
{
pages++;
SearchResponse response = connection.SendRequest(request) as SearchResponse;
//find the returned page response control
foreach (DirectoryControl control in response.Controls)
{
if (control is PageResultResponseControl)
{
//update the cookie for next set
prc.Cookie = ((PageResultResponseControl) control).Cookie;
break;
}
}
//add them to our collection
foreach (SearchResultEntry sre in response.Entries)
{
results.Add(sre);
}
//our exit condition is when our cookie is empty
if ( prc.Cookie.Length == 0 )
{
Trace.WriteLine( "Warning GetAllAdSdsp exiting in paged search wtih cookie = zero and page count =" + pages + " and user count = " + results.Count );
break;
}
}
return results;
}
It works perfectly on DEV and on Prod, but suddenly stopped working on the QA webserver when it talks to the QA AD server. it only returnes one page and then stops.
If I point DEV to the QA AD server it works correctly...
It was working before Feb 2012, last time I tested in QA, and definitely was broken in place by March 7, 2012
Can anyone think of anything that would cause this behavior? perhaps a windows update? I've had one jack this product up before...
I'm reasonably convinced that it's not the code or the configuration...as it works on so many other combinations... it's netowrk/securiyt/os related.. but I can't figure out what changed.
Any Help is appreicated
Had the exact same issue where no pages were returned after the first one.
Here is what I found to fix the problem:
PageResultRequestControl pageRequestControl = new PageResultRequestControl(500);
SearchOptionsControl soc = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
request.Controls.Add(pageRequestControl);
request.Controls.Add(soc);
No idea what the SearchOptionsControl does, but since I added this, AD returns all the expected objects.
This line solves the issue (connection is LdapConnection) ->
connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
https://social.msdn.microsoft.com/Forums/vstudio/en-US/17957bb2-15b4-4d44-80fa-9b27eb6cb61f/pageresultrequestcontrol-cookie-always-zero?forum=csharpgeneral

How do I implement a C# Thrift service and consume it with a Silverlight client?

I'm current looking at Thrift to use as a RPC framework for our apps (mostly written in C# and Silverlight). I've come as far as implementing a service and consuming it from a C# console app (using a socket as transport).
For the C# server side code my code looked like: (basically copying the tutorials included with the source code)
MyServiceHandler handler = new MyServiceHandler();
MyService.Processor processor = new MyService.Processor(handler);
TServerTransport serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(processor, serverTransport);
server.Serve();
For the client side code it looked like:
TTransport transport = new TSocket("localhost", 9090);
TProtocol protocol = new TBinaryProtocol(transport);
MyService.Client client = new MyService.Client(protocol);
transport.Open();
client.SomeServiceCall();
However, we will be consuming the service from a Silverlight client, and unfortunately there is no support for sockets in Silverlight for Thrift. I assume I'm forced to use HTTP communication between the client and service, using Thrift's C# THttpClient and THttpHandler classes? I could not find any examples of how to do this out there, can anyone point me in the right direction? Some example server and client side code would be appreciated.
It seems that this issue was already addressed by this guy. According to this JIRA, the fix is available in Thrift 0.9. You can either try this snapshot (note that, as it's not a final release, it might not be stable) or you can apply this patch to the 0.8 release.
I believe by now you would have understood, there is no direct way of communicating from Silverlight to the Cassandra database either using Thrift or any other clients.
I have one simple option related to this. Write a Silverlight enabled web service and consume it from the client.
For example, on the server side you can have a web service which does insert/update/read etc., like this. I just managed to pull out some code which we use for our project. Hope this helps.
using Apache.Cassandra;
using Thrift.Protocol;
using Thrift.Transport;
namespace CassandraWebLibrary
{
public class MyDb
{
String _host;
int _port;
String _keyspace;
bool _isConnected;
TTransport _transport = null;
Apache.Cassandra.Cassandra.Client _client = null;
String columnFamily = "ColumnFamilyName";
public VazhikaattiDB(String host, int port, String keyspace)
{
_host = host;
_port = port;
_keyspace = keyspace;
_isConnected = false;
}
public bool Connect()
{
try
{
_transport = new TFramedTransport(new TSocket(_host, _port));
TProtocol protocol = new TBinaryProtocol(_transport);
_client = new Apache.Cassandra.Cassandra.Client(protocol);
_transport.Open();
_client.set_keyspace(_keyspace);
_isConnected = true;
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
return _isConnected;
}
public bool Close()
{
if (_transport.IsOpen)
_transport.Close();
_isConnected = false;
return true;
}
public bool InsertData(Send your data as parameters here)
{
try
{
List<Column> list = new List<Column>();
string strKey = keyvalue;
#region Inserting into Coulmn family
List<Byte> valbytes = new List<byte>(BitConverter.GetBytes(value)); //You might have to pad this with more bytes to make it length of 8 bytes
Column doublecolumn1 = new Column()
{
Name = Encoding.UTF8.GetBytes("column1"),
Timestamp = timestampvalue,
Value = valbytes.ToArray()
};
list.Add(doublecolumn1);
Column stringcolumn2 = new Column()
{
Name = Encoding.UTF8.GetBytes("column2"),
Timestamp = timestampvalue,
Value = Encoding.UTF8.GetBytes("StringValue")
};
list.Add(stringcolumn2);
Column timecolumn3 = new Column()
{
Name = Encoding.UTF8.GetBytes("column3"),
Timestamp = timestampvalue,
Value = BitConverter.GetBytes(DateTime.Now.Ticks)
};
list.Add(timecolumn3);
#endregion
ColumnParent columnParent = new ColumnParent();
columnParent.Column_family = columnFamily;
Byte[] key = Encoding.UTF8.GetBytes(strKey);
foreach (Column column in list)
{
try
{
_client.insert(key, columnParent, column, ConsistencyLevel.QUORUM);
}
catch (Exception e)
{
log.Error(e.ToString());
}
}
return true;
}
catch (Exception ex)
{
log.Error(ex.ToString());
return false;
}
}
public List<YourReturnObject> GetData(parameters)
{
try
{
ColumnParent columnParent = new ColumnParent();
columnParent.Column_family = columnFamily;
DateTime curdate = startdate;
IndexExpression indExprsecondkey = new IndexExpression();
indExprsecondkey.Column_name = Encoding.UTF8.GetBytes("column");
indExprsecondkey.Op = IndexOperator.EQ;
List<Byte> valbytes = PadLeftBytes((int)yourid, 8);
indExprsecondkey.Value = valbytes.ToArray();
indExprList.Add(indExprsecondkey);
IndexClause indClause = new IndexClause()
{
Expressions = indExprList,
Count = 1000,
Start_key = Encoding.UTF8.GetBytes("")
};
SlicePredicate slice = new SlicePredicate()
{
Slice_range = new SliceRange()
{
//Start and Finish cannot be null
Start = new byte[0],
Finish = new byte[0],
Count = 1000,
Reversed = false
}
};
List<KeySlice> keyslices = _client.get_indexed_slices(columnParent, indClause, slice, ConsistencyLevel.ONE);
foreach (KeySlice ks in keyslices)
{
String stringcolumnvalue = Encoding.UTF8.GetString(cl.Column.Value);
double doublevalue= (Double)BitConverter.ToDouble(cl.Column.Value);
long timeticks = BitConverter.ToInt64(cl.Column.Value, 0);
DateTime dtcolumntime = new DateTime(timeticks);
}
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
return yourdatalist;
}
}
}
Now the above class can be used by your webservice, which in turn will be used by Silverlight. Btw, you'll have to take care of other silverlight issues like size of data to be downloaded from server/webservice etc.,
FYI, our client service of Cassandra runs on port 9160..

Categories