|
I have a couple of multiple queries that I have to perform that exist in 2 seperate methods. These methods are called within another method, where a SQLconnection is created and passed in to each of the queryMethods.
For some reason when I obtain the SQLDataReader ( = sqlCommand.ExecuteReader)
throws an error in the second method.
As soon as I use a seperate connection everything works, is there something that I don't understand here with using connections?
|
|
|
|
|
No, theres nothing special there. But without seeing your code and knowing EXACTLY what exception was thrown and the error message with it, we can only guess at what your problem is.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
here is the sub that is calling on the other methods
Private Sub RefreshData()<br />
<br />
While bRun<br />
<br />
Dim SqlConn As New SqlConnection(ModDb.ConnStr)<br />
Try<br />
SqlConn.Open()<br />
<br />
GetCourseList(SqlConn)<br />
If SelectedCourse Is Nothing = False Then<br />
GetFileList(SqlConn)<br />
End If<br />
<br />
SqlConn.Close()<br />
Catch ex As Exception<br />
If SqlConn.State = ConnectionState.Open Then<br />
SqlConn.Close()<br />
End If<br />
End Try<br />
<br />
Try<br />
trdQueryThread.Sleep(REFRESH_PERIOD)<br />
Catch ex As ThreadInterruptedException<br />
'do nothing<br />
Catch ex As Exception<br />
MessageBox.Show(ex.Message)<br />
End Try<br />
<br />
End While<br />
End Sub
Here is the first method that works fine
Private Sub GetCourseList(ByRef sqlConn As SqlConnection)<br />
<br />
Try<br />
Dim sqlCmd As New SqlCommand("dbo.LookupErrByCourseCode_npr", sqlConn)<br />
sqlCmd.CommandType = CommandType.StoredProcedure<br />
<br />
LstCourseCode.Items.Clear()<br />
LstCourseCode.Refresh()<br />
<br />
Dim sqlDR As SqlDataReader = sqlCmd.ExecuteReader<br />
<br />
While sqlDR.Read<br />
Dim course As New CourseDetails<br />
course.CourseCode = sqlDR.Item("Course Code")<br />
course.BoxNumber = sqlDR.Item("Box Number")<br />
course.ErrorCount = sqlDR.Item("Errors")<br />
LstCourseCode.Items.Add(course)<br />
End While<br />
<br />
Catch ex As Exception<br />
Dim myE As New MyException(ex, MyException.SeverityLevel.High)<br />
myE.WhatHappened = "GetCourseList: Error when obtaining Course Details"<br />
Throw myE<br />
End Try<br />
<br />
End Sub
Here is the second method that throws the exception on the SQLDataReader
Private Sub GetFileList(ByRef sqlConn As SqlConnection)<br />
<br />
lstTests.Items.Clear()<br />
<br />
Dim sqlCmd As New SqlCommand("dbo.CourseImage_npr", sqlConn)<br />
sqlCmd.CommandType = CommandType.StoredProcedure<br />
<br />
'reset the params due to selection of new course<br />
sqlCmd.Parameters.Add("@coursecode", SelectedCourse.CourseCode)<br />
sqlCmd.Parameters.Add("@boxnumber", SelectedCourse.BoxNumber)<br />
Try<br />
'====Right here is where it crashes when using the same connection<br />
Dim sqlDR As SqlDataReader = sqlCmd.ExecuteReader<br />
<br />
While sqlDR.Read<br />
'validate that the image exists<br />
Dim fileName As String = sqlDR.Item("image_path") & sqlDR.Item("image_name") & EXTENSION<br />
If IO.File.Exists(fileName) Then<br />
Dim image As New ImageDetails<br />
image.countSRE = sqlDR.Item("countSRE")<br />
image.imageId = sqlDR.Item("image_id")<br />
image.imageName = sqlDR.Item("image_name")<br />
image.imagePath = sqlDR.Item("image_path")<br />
lstTests.Items.Add(image)<br />
End If<br />
End While<br />
<br />
lstTests.Refresh()<br />
Catch ex As Exception<br />
Dim myE As New MyException(ex, MyException.SeverityLevel.High)<br />
myE.WhatHappened = "GetFileList: Error after sleeping"<br />
MessageBox.Show(myE.Message)<br />
'Throw myE<br />
End Try<br />
'End While<br />
<br />
End Sub
|
|
|
|
|
Your Connection code is a bit messed up. If anything fails inside that try block, the connection is never closed. On top of that, it's never disposed either. THis would result is a slow time for the garbage collector to get around freeing it. Also, put the connection close code in a Finally block so that it runs no matter what happens. And, when you check for the connection being opened, don't check for ConnectionState.Open. The connection state can be a combination of values that would no longer result in it being equal to ConnectionState.Open, even though it is. Instead, check for Not Equal to ConnectionState.Closed. The new code looks something like this:
Private Sub RefreshData()
While bRun
Dim SqlConn As New SqlConnection(ModDb.ConnStr)
Try
SqlConn.Open()
GetCourseList(SqlConn)
If SelectedCourse Is Nothing = False Then
GetFileList(SqlConn)
End If
Catch ex As Exception
' You might want to do something to report the error here.
Finally
If Not SqlConn.State = ConnectionState.Closed Then
SqlConn.Close()
End If
SqlConn.Dispose() ' Saves the GC a step in collecting this object.
SqlConn = Nothing ' Drop the reference so the GC collects it on the next pass.
End Try
Try
trdQueryThread.Sleep(REFRESH_PERIOD)
Catch ex As ThreadInterruptedException
'do nothing
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End While
End Sub
Also, in your MyException class, you might want to include the underlying Exception and error Message that was originally thrown. The exception your throwing isn't very descriptive as to what the real problem was.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
using threading with C# and ManagementObjectSearcher Object , i get a "random" COM Exception scanning XP and NT.. Any one have a clue??
|
|
|
|
|
Not without seeing your code. BTW: This is the VB.NET Forum, not C#...
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
oh soz didn't realize.. but maybe u can still help me? Ive been battling with this prob for a LONG time now..
Basically- i use: private ManagementObjectSearcher m_MOSearcher;
private ManagementScope m_ManScope;
private ConnectionOptions m_ConnectOptions;
m_ConnectOptions = new ConnectionOptions ();
m_ConnectOptions.Username = "user";
m_ConnectOptions.Password = "pass";
m_ConnectOptions.Authentication = AuthenticationLevel.Call;
m_ConnectOptions.Impersonation = ImpersonationLevel.Impersonate;
m_ConnectOptions.EnablePrivileges = true;
m_ConnectOptions.Locale = "MS_409";
m_ConnectOptions.Timeout = new TimeSpan (0,0,0,0,5);
string strConnection = "\\\\"+ "192.168.0.88" + "\\root\\cimv2";
m_ManScope = new ManagementScope(strConnection, m_ConnectOptions);
ObjectQuery Temp = new ObjectQuery("SELECT " + "Size" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Size: " +mo["Size"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "Model" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Model: " +mo["Model"].ToString ());
}
And thread it with:
for (int i=0; i< 250; i++)
{
Thread a = new Thread(new ThreadStart(Function));
a.Start();
}
i get a rpc error or COm exception sometimes?
maybe deadlock?
|
|
|
|
|
Your code never connects to the management source on the target machine. You need
m_ConnectOptions.Locale = "MS_409";
m_ConnectOptions.Timeout = new TimeSpan (0,0,0,0,5);
string strConnection = "\\\\"+ "192.168.0.88" + "\\root\\cimv2";
m_ManScope = new ManagementScope(strConnection, m_ConnectOptions);
m_ManScope.Connect();
ObjectQuery Temp = new ObjectQuery("SELECT " + "Size" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
Also, you don't have to perform two queries to get the result you want. One will suffice:
ObjectQuery Temp = new ObjectQuery("SELECT Size, Model FROM Win32_DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Size: " +mo["Size"].ToString ());
Console.WriteLine("Model: " +mo["Model"].ToString ());
}
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Hey thanks for the timely response!!
ah soz i forgot to paste that in!!(manscope.connect) sorry!
plz if u could try-> just request a whole lot of values from different tables.. and use threads (a lot).. and if u dont get an error maybe i can send u my program
2) Is there any windows setting(using XP) that can affect the WMI? I am unable to connect to some computers??
Thanks so much!
|
|
|
|
|
There are no settings that can affect WMI. I can't get the ManagementObjectSearcher class to work properly at all, either quering the local machine or a remote WMI namespace. The .Get() method works and returns, but the results are unreadable. I get a "COM object that has been separated from its underlying RCW can not be used." error in a Unhandled exception of type 'System.Management.ManagementException' occurred in system.windows.forms.dll when I try to get an enumerator for the returned object collection (ManagementObjectCollection.) But the entire WMI search code is wrapped in a Try/Catch block.
This error is getting back to the message pump unhandled for some reason. It looks like a bug in the .NET Framework, but I can't find any information on it. I also can't get a complete list of bug fixes in the upcomming Service Pack 1 for the .NET Framework 1.1 and SP3 for the .NET Framework 1.0. There are a LOT of bug fixes that don't have Knowledge Base articles for them yet...
Until the service pack comes out, I don't have a way around this problem.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Here's my code.. works for me..
Excuse the repertition, i just do this for complexities sake some RPC should occur if u use the threads...
using System;
using System.Threading;
using System.Management;
namespace SimpleTRY
{
public class Class1
{
private ManagementObjectSearcher m_MOSearcher;
private ManagementScope m_ManScope;
private ConnectionOptions m_ConnectOptions;
public Class1()
{
for (int i=0; i< 250; i++)
{
/*Thread a = new Thread(new ThreadStart(this.connect));
a.Start();*/
this.connect();
}
}
public void connect()
{
string ipAddress = "192.168.0.88";
m_ConnectOptions = new ConnectionOptions ();
m_ConnectOptions.Username = "Gorilla";
m_ConnectOptions.Password = "rock";
m_ConnectOptions.Authentication = AuthenticationLevel.Call;
m_ConnectOptions.Impersonation = ImpersonationLevel.Impersonate;
m_ConnectOptions.EnablePrivileges = true;
m_ConnectOptions.Locale = "MS_409";
m_ConnectOptions.Timeout = new TimeSpan (0,0,0,30);
string strConnection = "\\\\"+ ipAddress + "\\root\\cimv2";
m_ManScope = new ManagementScope(strConnection, m_ConnectOptions);
m_ManScope.Connect();
{
ObjectQuery Temp = new ObjectQuery("SELECT " + "Size" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Size: " +mo["Size"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "Model" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Model: " +mo["Model"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "SystemName" + " FROM Win32_" + "DiskDrive");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("SystemName: " +mo["SystemName"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "AdapterRAM" + " FROM Win32_" + "VideoController");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("AdapterRAM: " +mo["AdapterRAM"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "CurrentRefreshRate" + " FROM Win32_" + "VideoController");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("CurrentRefreshRate: " +mo["CurrentRefreshRate"].ToString ());
}
Temp = new ObjectQuery("SELECT " + "Name" + " FROM Win32_" + "VideoController");
m_MOSearcher = new ManagementObjectSearcher (m_ManScope, Temp);
foreach(ManagementObject mo in m_MOSearcher.Get())
{
Console.WriteLine("Name: " +mo["Name"].ToString ());
}
Console.WriteLine("--------------------------------------");
}
}
}
}
|
|
|
|
|
Now I get your problem. The issue is your swamping the target machine with requests. You have to pace your request by dropping in a Thread.Sleep() right after your Thread.Start(). What's happening is by launching 250 requests, at nearly the same time, the WMI service on the target machine can't keep up. Your pegging the target machines CPU Utilization at 100% the entire time your making these requests. In order to get it to work reliably, I had to pace the thread launches at every 150 milliseconds. This was by no means an extensive test, so for reliability, you'd probably have to increase that number to 250 milliseconds. THe only way to guarantee that it won't fail, is to launch them one at a time and wait for each request to complete before you launch the next one.
BTW: Why on earth would you want to do this? The only reason I can see is that your launching 250 requests at 250 seperate machines, not the same machine. This requirement would invalidate any testing your doing because you ar no longer stressing a single target machine.
A better way to do this would be to queue the work using the .NET Frameworks' built in ThreadPool.
public Class1()
{
for (int i=0; i< 250; i++)
{
Thread a = new Thread(new ThreadStart(this.connect));
a.Start();
Thread.Sleep(150);
}
}
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Why i am doing this incredibly daft task is to test the ManagementObjectSearcher Class.. because: i have another program that does retrieve info from many different comps.. the prob is while im scanning them, sometimes all of a sudden i get an RPC fail or COMException.. SO i want to make sure it's WMI setting or possibly a bug.
To Me, Something seems fishy with remotly retrieving the info.. Everything works fine locally. please try again with my code, using no threads (just "connect()") and see if u get the error? after it has gone thru the loop about 95 times the Exception pops up?
Thanks
|
|
|
|
|
Well, I ran the code like this:
public Class2()
{
for (int i=0; i< 25000; i++)
{
this.connect();
}
}
and didn't have a single problem...
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Then I tried it like this:
public Class2()
{
for (int i=0; i< 2500; i++)
{
Thread a = new Thread(new ThreadStart(this.connect));
a.Start();
Thread.Sleep(500);
}
}
and couldn't get it to work reliably until I increased the Sleep delay to half a second. Took forever to run, but...
My suggestion still stands, queue up the work in the .NET Thread Pool.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
ja with the first 1: my problems are rare... most of the times it works.. but it's like the WMI on the remote computer gets clogged up from the previous attempts (when i ran the program before)
it's funny - i changed the password on the remote comp and now with threads i get an UnauthorizedAccessException sometimes..
NE Ways il let u know wat happens
|
|
|
|
|
hi - thread pool still gives me problems.. um i dont wanna worry about threads atm.. rather, plz could u just use the connect (no threads) and run the exe in the debug folder at the same time.. i would like to know if u also get and RPC error? if u dont get one at first, just keep running the program and exe thanks..
Another thing-do u know how to pass Credentials to be able to access the registry? Im using RegistryKey and OpenRemoteBaseKey...
thanks again
|
|
|
|
|
Okay. Now I’m making some progress. Thanks, beowulfagate, for suggesting the GetThumbnailImage method.
Can anybody tell me how to use the GetThumbnailImage method to fill a ListView?
Here is what I have:
lstPhotos.BeginUpdate()<br />
lstPhotos.Items.Clear()<br />
Dim strFiles() As String<br />
Dim x As Integer<br />
strFiles = Directory.GetFiles(formLibrary.componentPath)<br />
For x = 0 To strFiles.Length - 1<br />
Dim objListViewItem As New ListViewItem<br />
Dim imageThumb As Image<br />
With objListViewItem<br />
.Text = Path.GetFileName(strFiles(x))<br />
.SubItems.Add(Format(FileLen((strFiles(x))), "###,###,###,###"))<br />
.SubItems.Add(CStr(File.GetLastWriteTime(strFiles(x))))<br />
End With<br />
lstPhotos.Items.Add(objListViewItem)<br />
<br />
Next x<br />
lstPhotos.EndUpdate()
This lists the contents of the formLibrary.componentPath folder but I can't see how to use GetThumbnailImage to display the images as thumbnails in lstPhotos .
Thanks.
Brad
|
|
|
|
|
...I'm waayyy off aren't I?
The more I dig, the more I realize that I have no idea what I'm doing.
I wonder if I should try to use the StateImageList property?
Can anybody help?
Brad
|
|
|
|
|
try this:
<br />
dim imagethumb as image<br />
imagethumb.fromfile=path.getfilename(strFiles(x))<br />
dim index as integer=lstphotos.largeimagelist.images.add(imagethumb.getThumbNailImage)<br />
lstphotos.items.add(path.getfilename(strFiles(x),index)<br />
Note: the listview should be in the LargeIcons Style to use the LargeImageList. Use the SmallIcons to use the SmallImageList.
|
|
|
|
|
I can’t get imagethumb.fromfile to work. It says: Overload resolution failed because no accessible ‘FromFile’ accepts this number of arguments.
At first I thought that this might be because strFiles is and array but that didn’t seem to be causing the problem.
|
|
|
|
|
Uh Oh! Sorry. Try this.
<br />
Imagethumb.fromfile(path.getfilename(strFiles(x))<br />
|
|
|
|
|
That did the trick. Thanks!
Now the Index variable is giving me a fit.
Dim index As Integer = lstPhotos.LargeImageList.Images.Add(imagethumb.GetThumbnailImage )
Should index be declared as something other than an Integer since an image is being assigned to it? Is so, do you know what it would be?
Thanks
Brad
|
|
|
|
|
No, it is not an image being assigned to it. It is the index of the image we just added to the imagelist. We need this index to know what index goes with what item. The add method of the ImageCollection Class is declared as:
<br />
public sub overloads Add(icon)<br />
public sub overloads Add(Image) 'We are using this<br />
public function overloads Add(Image,Color) as integer 'When we should be using this<br />
Just add a color parameter to the Add method and it should work fine. Look it up in the MSDN Library.
|
|
|
|
|
Thanks.
I think I'm on track now.
Brad
|
|
|
|