|
It's the second method call that's the problem. No mutex, monitor or lock statement can help you here as they are all concerned about threading.
But the output clearly says that you're running multithreaded. The lockedFunction2() invocation will not execute before lockedFunction1() is finished. To get the output you display, lockedFunction1(), lockedFunction2() or both must start another thread that outputs the text.
To test for this you could make this change to the output routine:
Console.WriteLine("function 1 entered in thread: " + System.Threading.Thread.CurrentThread.GetHashCode() );
if the hashcode differs in the output, then it's another thread. If it doesn't, then call an Exorcist
"God doesn't play dice" - Albert Einstein
"God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr
|
|
|
|
|
Know any good ones
entered commandSetBlockParameter in thread: 20
Exited commandSetBlockParameter in thread: 20
entered queryBlockParameter in thread: 20
entered commandSetBlockParameter in thread: 20
Exited commandSetBlockParameter in thread: 20
entered queryBlockParameter in thread: 20
entered commandSetBlockParameter in thread: 20
Exited commandSetBlockParameter in thread: 20
entered queryBlockParameter in thread: 20
Exited queryBlockParameter in thread: 20
Exited queryBlockParameter in thread: 20
That said, Let me add another issue. This is in a timer loop. The timer was ticking before the last passthrough finished. I can disable the timer until the loop completes than reenable it. This may be the only way to fix this.
However, The same problem happens elsewhere when I subscribe to an event and I end up writing two values. I will have to fix this and do more testing. Please do not give up on me. You have been a HUGE help. If I respond in a day, will you be here, or should I start a new thread?
Thanks so much...
Dwayne
*****************
"We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW
|
|
|
|
|
ok. I have updated the rest of the code and am able to stop it from happening in the timer by disabling it and reenabling it after the loop completes. The same problem still applies to when I subscribe to an event, this launches a new set of code (still in the same thread according to the output) that runs and overlaps.
For instance... the original description of two userControls each calling the same communications function. When the user selects the second control it send a stop message to the first control, but that does not stop the form from continuing through it's timer poll. It is in these transitions that the problem still happens.
-Dwayne
*****************
"We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW
|
|
|
|
|
I'm baffled. I can't imagine how you can possibly get such a result. Look at this, ugly, code:
using System;
using System.Threading;
using System.IO;
namespace ConsoleTestApp
{
public class MyClass
{
private Timer timer;
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
using (FileStream fileStream = File.OpenWrite(@"C:\test.txt"))
{
using (StreamWriter sw = new StreamWriter(fileStream))
{
Console.SetOut(sw);
myClass.Start();
Thread.Sleep(10000);
myClass.Stop();
Thread.Sleep(1000);
}
}
}
public void Start()
{
timer = new Timer( new TimerCallback(MyTimerCallback), null, 0, 500 );
}
public void Stop()
{
timer.Dispose();
}
private void MyTimerCallback(object state)
{
for (int i = 0; i < 5; i++)
{
Foo();
}
}
private void Foo()
{
lock (this)
{
Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
Thread.Sleep(100);
Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
}
}
}
}
It doesn't produce the outcome you get. Does your code look something like this?
"God doesn't play dice" - Albert Einstein
"God not only plays dice, He sometimes throws the dices where they cannot be seen" - Niels Bohr
|
|
|
|
|
Not really.
It would be more like:
using System;
using System.Threading;
using System.IO;
namespace ConsoleTestApp
{
public class MyClass
{
private Timer timer;
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
timer.Interval=100;
timer.Enabled=true;
timer.Tick += new System.EventHandler(this.timer_Tick);
}
public void timer_Tick()
{
Foo1();
Foo2();
}
private void Foo1()
{
lock(LockClass.LOCK_OBJECT)
{
Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
Thread.Sleep(100);
Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
}
}
private void Foo2()
{
lock(LockClass.LOCK_OBJECT)
{
Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
Thread.Sleep(200);
Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
}
}
}
public class LockClass
{
public static readonly object LOCK_OBJECT = new object();
}
}
This was typed so my syntax may not be exact. There is also no start and stop events. this is mainly to let you get the idea.
As you can see it takes more time for the Foos to run that it takes for the timer to start the next tick. so the timer ticks and foo1 is started again while foo2 is still running.
So instead of this... I am putting the following in the Timer code:
public void timer_Tick()
{
try
{
timer.enabled = false;
Foo1();
Foo2();
}
finally
{
timer.enabled = true;
}
}
It is a patch, but it works. I am uncertain of the TimerCallBack. I will spend tonight figuring out that. Perhaps I am not using the Timer properly.
I must admit, I had/have little experience with the timers.
The other problem is when I subscribe to an event:
using System;
using System.Threading;
using System.IO;
namespace ConsoleTestApp
{
public class MyClass
{
private Timer timer;
private bool doStop1;
private bool doStop2;
private Button RunFoo2;
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
timer1.Interval=100;
timer1.Enabled=true;
timer1.Tick += new System.EventHandler(this.timer_Tick);
timer2.Interval=100;
timer2.Enabled=false;
timer2.Tick += new System.EventHandler(this.timer_Tick);
RunFoo2.Click += new System.EventHandler(this.RunFoo2_Click);
}
public void RunFoo2_Click()
{
doStop1 = true;
timer2.enabled = true;
}
public void timer1_Tick()
{
try
{
timer1.enabled = false;
Foo1();
Foo2();
}
finally
{
if(!doStop1)
{
timer1.enabled = true;
}
}
}
public void timer2_Tick()
{
try
{
timer2.enabled = false;
Foo1();
Foo2();
}
finally
{
if(!doStop2)
{
timer2.enabled = true;
}
}
}
private void Foo1()
{
lock(LockClass.LOCK_OBJECT)
{
Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
Thread.Sleep(100);
Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
}
}
private void Foo2()
{
lock(LockClass.LOCK_OBJECT)
{
Console.WriteLine("Entered lock block in thread " + Thread.CurrentThread.GetHashCode());
Thread.Sleep(200);
Console.WriteLine("Leaving lock block in thread " + Thread.CurrentThread.GetHashCode());
}
}
}
public class LockClass
{
public static readonly object LOCK_OBJECT = new object();
}
}
Thanks again.
-Dwayne
*****************
"We need to apply 21st-century information technology to the health care field. We need to have our medical records put on the I.T." —GW
|
|
|
|
|
hello friends
Reading c# books take a lot of my time
please can somebody give me a site where i can download
free C# videos
|
|
|
|
|
|
Im in the process of learning C#, and so far, I'm loving it. I've found a way to make calls to some old "C" DLLs, but I have a few questions regarding types.
[DllImport("MYDLL.DLL")]
public static extern ulong GetSerialNumbers ( byte f1, byte f2, byte NodeAddr, PIFS_CABLESER pserials, PUSHORT pcount );
I have a function in in MYDLL.DLL called GetSerialNumbers that returns an array of structures. I have no problems declaring functions with known types, but as soon as I add in a type that C# doesn't know, I'm stuck. I would like to take the data of these structures and copy them to a class I've created....
This is my C definition, would I have to make something equivalent that C# will understand?
typedef struct SerialInfoMD
{
byte ID[8];
byte something;
int new;
} IFS_CABLESER, *PIFS_CABLE_SER;
Anybody have any info to share?
Thanks!
Mike
|
|
|
|
|
Yes, as with the requirement of defining the function signature in C# you also have to supply a description of the structure as well. For the structure you provided the sig would be
[StructLayout(LayoutKind.Sequential)]
struct SerialInfoMD
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public byte[] ID;
public byte Something;
public int New; // note the capitalization change. Syntax error otherwise.
}
Things can get tricky when marshalling data between managed and unmanaged code. For example, in your function signature you have the return type as ulong. Is the return type for the C function an unsigned long? Unsigned long is 32-bits on Win32 but is 64-bits on .NET so the appropriate return type in the C# method is uint if the return type on the C function is unsigned long. It gets even more murky when dealing with arrays. You might wanna check out information on data marshalling on MSDN. Try this URL for a start.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconInteropMarshaling.asp
|
|
|
|
|
hello, i need to change the scroll bar color for a ListView (i'm trying to make a flat gui). Can u plese help? Thx
|
|
|
|
|
You have to use css for that, and it will only work in Internet Explorer.
---
b { font-weight: normal; }
|
|
|
|
|
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2600&lngWId=10
Live Life King Size
Alomgir Miah
|
|
|
|
|
I need to create a Bitmap of a datagrid. Is there a way to do this?
|
|
|
|
|
VS.NET executes the code behind Propertys when you change them in the property grid in the designer. Is there anyway to modify the code such that it knows when it's being changed via the designer? There is some code in my get/set that has some unwanted side effects during design time.
|
|
|
|
|
|
Hi all.
I have a strange problem with Webservices:
In a webmethod I modify the value of a variable (string) inside an instance of a class that I created. When the webmethod returns, the change of the string is lost, and it returns to its initial value.
a concrete example
class MyClass {
private string s;
public string String {
get { return s; }
set { s = value; }
}
}
private MyClass data = new MyClass();
[WebMethod()]
public MyMethod(string s) {
data.String = s;
// Consume data.String -> correct value
}
private void otherMethod() {
// Consume data.String -> WRONG VALUE
}
The webservice calls MyMethod().
In a successive call to another webmethod, otherMethod() is called and the data.String value is wrong!!!
I tries to use methods Set() Get() instead of the public property but nothing changes.
Maybe I don't know an important thing???
Any help will be very ... HELPFUL!
|
|
|
|
|
|
Yeah! I'm so idiot! I know that! thank you for this mind shake! somethimes the simplest solution is there and you cannot see it...
|
|
|
|
|
Hello,
Is there a way of making the ComboBox as a typeahead?
In otherer words, user can't modify the text, but if start typing it will give you the corresponding entries in the dropdown list, depending on the string that user enters.
Thank you
|
|
|
|
|
private void ComboBox1_KeyUp(Object sender,System.Windows.Forms.KeyEventArgs e)
}
AutoCompleteCombo(ComboBox1,e);
}
public static void AutoCompleteCombo(ComboBox cbo,KeyEventArgs e)
{
String sTypedText;
Int32 iFoundIndex;
Object oFoundItem;
String sFoundText ;
String sAppendText ;
//'Allow select keys without Autocompleting
switch (e.KeyCode)
{
case Keys.Back:
break;
case Keys.Left:
break;
case Keys.Right:
break;
case Keys.Tab:
break;
case Keys.Up:
break;
case Keys.Delete:
break;
case Keys.Down:
break;
}
//'Get the Typed Text and Find it in the list
sTypedText = cbo.Text;
iFoundIndex = cbo.FindString(sTypedText);
//'If we found the Typed Text in the list then Autocomplete
if (iFoundIndex >= 0)
{ //'Get the Item from the list (Return Type depends if Datasource was bound
//' or List Created)
oFoundItem = cbo.Items[iFoundIndex];
//'Use the ListControl.GetItemText to resolve the Name in case the Combo
//' was Data bound
sFoundText = cbo.GetItemText(oFoundItem);
//'Append then found text to the typed text to preserve case
sAppendText = sFoundText.Substring(sTypedText.Length);
cbo.Text = sTypedText.ToString() + sAppendText.ToString();
//'Select the Appended Text
cbo.SelectionStart = sTypedText.Length;
cbo.SelectionLength = sAppendText.Length;
}
}
Live Life King Size
Alomgir Miah
|
|
|
|
|
Thank you.
Do I have to change the property of the DropDownStyle?
|
|
|
|
|
DropDownStyle should be
DropDown
Live Life King Size
Alomgir Miah
|
|
|
|
|
You can use autoComplete combobox or modify it
if you search site here you will find some of them
like this
like this[^]
MCAD
|
|
|
|
|
I am trying to create a DTS package using C#. I have done this in VB6 without any problems. However, when I convert everything over to C# I
get the 'System.InvalidCastException'. I am running windows 2000, SQL
2000 sp3a. I have also followed the instructions in using DTS provided
by "http://sqldev.net/DTS/dotnetcookbook.htm".
The error is occurs at this line:
<br />
DTS.DataPumpTask DT = (DTS.DataPumpTask)package.Tasks.New <br />
("DTSDataPumpTask"); <br />
Does anyone know what causes this and is there a fix for it?
Below is a copy of the code.
<br />
public void createPackag() <br />
{ <br />
DTS.Connection oConnection = <br />
(DTS.Connection)package.Connections.New("Microsoft.Jet.OLEDB.4.0"); <br />
<br />
<br />
oConnection.Name ="Connection 1"; <br />
oConnection.DataSource = "C:\\MySourceDB.MDB"; <br />
oConnection.ID = 1; <br />
oConnection.Reusable = true; <br />
oConnection.ConnectImmediate = false; <br />
oConnection.ConnectionTimeout = 60; <br />
oConnection.UseTrustedConnection = false; <br />
oConnection.UseDSL = false; <br />
oConnection = null; <br />
DTS.Connection oConnection2 = <br />
(DTS.Connection)package.Connections.New("SQLOLEDB"); <br />
oConnection2.Name = "Connection 2"; <br />
oConnection2.ID = 2; <br />
oConnection2.Reusable = true; <br />
oConnection2.ConnectImmediate= false; <br />
oConnection2.DataSource= "MyServerName"; <br />
oConnection2.UserID = "MyUserID"; <br />
oConnection2.ConnectionTimeout = 60; <br />
oConnection2.Catalog = "MyDestDB"; <br />
oConnection2.UseTrustedConnection = false; <br />
oConnection2.UseDSL = false; <br />
oConnection2.Password = "MyPassword"; <br />
oConnection2 = null; <br />
DTS.Step2 oStep = <br />
(DTS.Step2)package.Steps.New(); <br />
oStep.Name = "Copying Data from MyTable"; <br />
oStep.Description = "Copying Data from <br />
MyTable"; <br />
oStep.TaskName = "Copying Data from MyTable"; <br />
oStep.CommitSuccess = false; <br />
oStep.RollbackFailure = false; <br />
oStep.ScriptLanguage = "VBScript";
about this <br />
oStep.AddGlobalVariables = true; <br />
oStep.CloseConnection = false; <br />
oStep.ExecuteInMainThread = true; <br />
oStep.IsPackageDSORowset = false; <br />
oStep.JoinTransactionIfPresent = false; <br />
oStep.DisableStep = false; <br />
oStep.FailPackageOnError = true; <br />
package.Steps.Add(oStep); <br />
oStep = null; <br />
DTS.Task oTask = <br />
(DTS.Task)package.Tasks.New("DTSDataPumpTask"); <br />
oTask.Name = "Copying Data from MyTable"; <br />
DTS.CustomTask oCustomTask = oTask.CustomTask; <br />
oCustomTask.Name = "Copying Data from MyTable"; <br />
<br />
<br />
oCustomTask.Description = "Copying Data from <br />
MyTable to <br />
MyDestDB.MyTable"; <br />
DTS.DataPumpTask DT = <br />
(DTS.DataPumpTask)package.Tasks.New("DTSDataPumpTask"); <br />
DT.SourceConnectionID = 1; <br />
DT.SourceSQLStatement = "SELECT `TestField` <br />
FROM MyTable"; <br />
DT.DestinationConnectionID =2; <br />
DT.DestinationObjectName = "MyTable"; <br />
DT.ProgressRowCount = 1000; <br />
DT.MaximumErrorCount = 0; <br />
DT.FetchBufferSize = 1; <br />
DT.UseFastLoad=true; <br />
DT.InsertCommitSize = 0; <br />
DT.InsertCommitSize = 500000; <br />
DT.ExceptionFileColumnDelimiter = "|"; <br />
DT.ExceptionFileRowDelimiter = "\r\n"; <br />
DT.AllowIdentityInserts = false; <br />
DT.FirstRow = 0; <br />
DT.LastRow = 0; <br />
DTS.Transformation Trans = <br />
(DTS.Transformation)package.Tasks.New("DataPumpTransformCopy"); <br />
Trans.Name = "DirectCopyXform"; <br />
Trans.TransformFlags = 63; <br />
Trans.ForceSourceBlobsBuffered = 0; <br />
Trans.ForceBlobsInMemory = false; <br />
Trans.InMemoryBlobSize = 1048576; <br />
Trans.SourceColumns.AddColumn("TestField",1); <br />
<br />
<br />
Trans.DestinationColumns.AddColumn("TestField",1); <br />
DT.Transformations.Add(Trans); <br />
package.Tasks.Add(oTask); <br />
oCustomTask = null; <br />
oTask = null; <br />
<br />
<br />
} <br />
<br />
|
|
|
|
|
I was able to resolve this issue and thought I would post the solution so that others may benefit from it. The following example creates, saves, and executes a DTS package in C#. This example is setup to only DTS one field from one table but it can easily be modified to do a complete database.
This particular section of code gave me the most trouble so I thought I would point it out as well. My original code looked like this and would cause an invalidcastexception.
<br />
DTS.Task oTask = (DTS.Task)package.Tasks.New("DTSDataPumpTask");<br />
DTS.CustomTask oCustomTask = oTask.CustomTask;<br />
This was how I corrected it.
<br />
DTS.DataPumpTask2 oCustTask;<br />
DTS.Task oTask;<br />
oTask = pkg.Tasks.New("DTSDataPumpTask");<br />
oCustTask = (DTS.DataPumpTask2)oTask.CustomTask;<br />
Here is the entire example:
<br />
using System;<br />
using System.Drawing;<br />
using System.Collections;<br />
using System.ComponentModel;<br />
using System.Windows.Forms;<br />
using System.Data;<br />
using DTS = Microsoft.SQLServer.DTSPkg80;<br />
<br />
namespace MyDTSTest<br />
{<br />
public class Form1 : System.Windows.Forms.Form<br />
{<br />
private System.ComponentModel.Container components = null;<br />
private System.Windows.Forms.Button button1;<br />
public DTS.Package2Class pkg = new DTS.Package2Class();<br />
<br />
private void button1_Click(object sender, System.EventArgs e)<br />
{<br />
initpackage();<br />
}<br />
<br />
public void initpackage()<br />
{<br />
CreateConnections();<br />
CreatePackageSteps();<br />
DefinTasks(pkg);<br />
pkg.Name="MyCSharpDTSTest";<br />
pkg.Description = "CShart DTS Test";<br />
object MIA=System.Reflection.Missing.Value;<br />
pkg.SaveToSQLServer("MyServerName", "MyUserID", "MyPassword", <br />
DTS.DTSSQLServerStorageFlags.DTSSQLStgFlag_Default, "","","",ref MIA,false);<br />
pkg.Execute();<br />
pkg.UnInitialize();<br />
pkg = null;<br />
}<br />
<br />
public void CreateConnections()<br />
{<br />
<br />
DTS.Connection oConnection = (DTS.Connection)pkg.Connections.New("Microsoft.Jet.OLEDB.4.0");<br />
oConnection.Name ="Connection 1";<br />
oConnection.DataSource = "C:\\MySoureDB.MDB";<br />
oConnection.ID = 1;<br />
oConnection.Reusable = true;<br />
oConnection.ConnectImmediate = false;<br />
oConnection.ConnectionTimeout = 60;<br />
oConnection.UseTrustedConnection = false;<br />
oConnection.UseDSL = false;<br />
pkg.Connections.Add(oConnection);<br />
oConnection = null;<br />
DTS.Connection oConnection2 = (DTS.Connection)pkg.Connections.New("SQLOLEDB");<br />
oConnection2.Name = "Connection 2"; <br />
oConnection2.ID = 2;<br />
oConnection2.Reusable = true;<br />
oConnection2.ConnectImmediate= false;<br />
oConnection2.DataSource= "MyServerName";<br />
oConnection2.UserID = "MyUserID";<br />
oConnection2.ConnectionTimeout = 60;<br />
oConnection2.Catalog = "MyDestDB";<br />
oConnection2.UseTrustedConnection = false;<br />
oConnection2.UseDSL = false;<br />
oConnection2.Password = "MyPassword";<br />
pkg.Connections.Add(oConnection2);<br />
oConnection2 = null;<br />
}<br />
<br />
public void CreatePackageSteps()<br />
{<br />
DTS.Step2 oStep = (DTS.Step2)pkg.Steps.New();<br />
oStep.Name = "Copying Data from myTableName";<br />
oStep.Description = "Copying Data from myTableName";<br />
oStep.TaskName = "Copying Data from myTableName";<br />
oStep.CommitSuccess = false;<br />
oStep.RollbackFailure = false;<br />
oStep.ScriptLanguage = "VBScript";<br />
oStep.AddGlobalVariables = true;<br />
oStep.CloseConnection = false;<br />
oStep.ExecuteInMainThread = true;<br />
oStep.IsPackageDSORowset = false;<br />
oStep.JoinTransactionIfPresent = false;<br />
oStep.DisableStep = false;<br />
oStep.FailPackageOnError = true;<br />
pkg.Steps.Add(oStep);<br />
oStep = null;<br />
<br />
}<br />
<br />
public void DefinTasks(DTS.Package2Class package)<br />
{<br />
DTS.DataPumpTask2 oCustTask;<br />
DTS.Task oTask;<br />
oTask = pkg.Tasks.New("DTSDataPumpTask");<br />
oCustTask = (DTS.DataPumpTask2)oTask.CustomTask;<br />
oCustTask.Name = "Copying Data from myTableName";<br />
oCustTask.Description = "Copying Data from myTableName to MyDestDB.myTableName";<br />
DTS.DataPumpTask2 oDataPump = (DTS.DataPumpTask2)oTask.CustomTask;<br />
oDataPump.SourceConnectionID = 1;<br />
oDataPump.SourceSQLStatement = "SELECT `MyField` FROM myTableName";<br />
oDataPump.DestinationConnectionID =2;<br />
oDataPump.DestinationObjectName = "myTableName";<br />
oDataPump.ProgressRowCount = 1000;<br />
oDataPump.MaximumErrorCount = 0;<br />
oDataPump.FetchBufferSize = 1;<br />
oDataPump.UseFastLoad=true;<br />
oDataPump.InsertCommitSize = 0;<br />
oDataPump.InsertCommitSize = 500000;<br />
oDataPump.ExceptionFileColumnDelimiter = "|";<br />
oDataPump.ExceptionFileRowDelimiter = "\n\r";<br />
oDataPump.AllowIdentityInserts = false;<br />
oDataPump.FirstRow = 0;<br />
oDataPump.LastRow = 0;<br />
CreateTaskTrans(oDataPump, oCustTask);<br />
pkg.Tasks.Add(oTask);<br />
oCustTask = null;<br />
oTask = null;<br />
<br />
}<br />
public void CreateTaskTrans(DTS.DataPumpTask DatPump, DTS.DataPumpTask2 CustTask)<br />
{<br />
DTS.Transformation2 oTransformation;<br />
oTransformation = (DTS.Transformation2)CustTask.Transformations.New("DTS.DataPumpTransformCopy");<br />
oTransformation.Name = "DirectCopyXform";<br />
oTransformation.TransformFlags = 63;<br />
oTransformation.ForceSourceBlobsBuffered = 0;<br />
oTransformation.ForceBlobsInMemory = false;<br />
oTransformation.InMemoryBlobSize = 1048576;<br />
oTransformation.SourceColumns.AddColumn("MyField",1);<br />
oTransformation.DestinationColumns.AddColumn("MyField",1);<br />
DatPump.Transformations.Add(oTransformation);<br />
<br />
}<br />
}<br />
}
|
|
|
|