Showing posts with label static. Show all posts
Showing posts with label static. Show all posts

Saturday, March 31, 2012

There is no consumer connection point 'IMessageConsumer' on 'bla [2]'.

I created a static connected webpart.

INTERFACE:
public interface IMessage
{
string Message { get;}
}

USERCONTROL PROVIDER:
public partial class Control1 : System.Web.UI.UserControl, IMessage,
IWebPart
{
protected void Page_Load(object sender, EventArgs e)
{

}
[ConnectionProvider("Message","IMessageProvider")]
public IMessage GetMessage()
{
return this;
}
public string Message
{
get
{
return TextBox1.Text;
}
}

#region IWebPart Members (ETC)

USERCONTROL CONSUMER
public partial class Control2 : System.Web.UI.UserControl, IWebPart
{
protected void Page_Load(object sender, EventArgs e)
{

}

private IMessage _message;

[ConnectionConsumer("Message","IMessageConsumer",AllowsMultipleConnections=true)]
void SetMessage(IMessage message)
{
this._message = message;
}

protected override void OnPreRender(EventArgs e)
{
if (_message != null)
Label1.Text = _message.Message;
base.OnPreRender(e);
}
#region IWebPart Members (ETC)

DEFAULT.ASPX:

<body>
<form id="form1" runat="server">

<div>
<asp:WebPartManager ID="WebPartManager1" runat="server"
Personalization-Enabled="true">
<StaticConnections>
<asp:WebPartConnection ID="conId"
ConsumerID="dataConsumer" ProviderID="dataProvider"
ConsumerConnectionPointID="IMessageConsumer"
ProviderConnectionPointID="IMessageProvider" />
</StaticConnections>

</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<uc1:Control1 ID="dataProvider" runat="server" />
<uc2:Control2 ID="dataConsumer" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>

</div>
</form>
</body>

And I get this error :"There is no consumer connection point
'IMessageConsumer' on 'bla [2]'. "... Checkded it with multiple
tutorials, but can't find what I'm doing wrong.

Hope someone can help me!
Regards,
PatrickUSERCONTROL CONSUMER

Quote:

Originally Posted by

public partial class Control2 : System.Web.UI.UserControl, IWebPart
{
protected void Page_Load(object sender, EventArgs e)
{
>
}
>
private IMessage _message;
>
[ConnectionConsumer("Message","IMessageConsumer",AllowsMultipleConnections=*true)]
void SetMessage(IMessage message)
{
this._message = message;
}
>


Solved it, I forgot to make the SetMessage public ;-)

There is no consumer connection point 'IMessageConsumer' on 'bla '.

I created a static connected webpart.
INTERFACE:
public interface IMessage
{
string Message { get;}
}
USERCONTROL PROVIDER:
public partial class Control1 : System.Web.UI.UserControl, IMessage,
IWebPart
{
protected void Page_Load(object sender, EventArgs e)
{
}
[ConnectionProvider("Message","IMessageProvider")]
public IMessage GetMessage()
{
return this;
}
public string Message
{
get
{
return TextBox1.Text;
}
}
#region IWebPart Members (ETC)
USERCONTROL CONSUMER
public partial class Control2 : System.Web.UI.UserControl, IWebPart
{
protected void Page_Load(object sender, EventArgs e)
{
}
private IMessage _message;
[ConnectionConsumer("Message","IMessageConsumer",AllowsMultipleConnections=t
rue)]
void SetMessage(IMessage message)
{
this._message = message;
}
protected override void OnPreRender(EventArgs e)
{
if (_message != null)
Label1.Text = _message.Message;
base.OnPreRender(e);
}
#region IWebPart Members (ETC)
DEFAULT.ASPX:
<body>
<form id="form1" runat="server">
<div>
<asp:WebPartManager ID="WebPartManager1" runat="server"
Personalization-Enabled="true">
<StaticConnections>
<asp:WebPartConnection ID="conId"
ConsumerID="dataConsumer" ProviderID="dataProvider"
ConsumerConnectionPointID="IMessageConsumer"
ProviderConnectionPointID="IMessageProvider" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<uc1:Control1 ID="dataProvider" runat="server" />
<uc2:Control2 ID="dataConsumer" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</div>
</form>
</body>
And I get this error :"There is no consumer connection point
'IMessageConsumer' on 'bla [2]'. "... Checkded it with multiple
tutorials, but can't find what I'm doing wrong.
Hope someone can help me!
Regards,
Patrick> USERCONTROL CONSUMER
> public partial class Control2 : System.Web.UI.UserControl, IWebPart
> {
> protected void Page_Load(object sender, EventArgs e)
> {
> }
> private IMessage _message;
> [ConnectionConsumer("Message","IMessageConsumer",AllowsMultipleConnection=
s=3D=ADtrue)]
> void SetMessage(IMessage message)
> {
> this._message =3D message;
> }
>
Solved it, I forgot to make the SetMessage public ;-)

Wednesday, March 28, 2012

This could be shorter tight? (String to Hex)

public static String StringToHex(String sString)
{
if (sString.Length == 0) { return ""; }
StringBuilder sb = new StringBuilder(sString.Length * 2);
Char[] chars = sString.ToCharArray();
String T = "";
foreach (Char c in chars)
{
T = "0" + Convert.ToString(c, 16).ToUpper();
sb.Append(T.Substring (T.Length -2 ));
}
return sb.ToString();
}Sorry, did not understand from your code what is this function suppose to
do.
Please tell us what you want to get out of the function with name
StringToHex

George.

"Edwin Knoppert" <news@.hellobasic.com> wrote in message
news:43f5dbbb$0$2025$ba620dc5@.text.nova.planet.nl. ..
> public static String StringToHex(String sString)
> {
> if (sString.Length == 0) { return ""; }
> StringBuilder sb = new StringBuilder(sString.Length * 2);
> Char[] chars = sString.ToCharArray();
> String T = "";
> foreach (Char c in chars)
> {
> T = "0" + Convert.ToString(c, 16).ToUpper();
> sb.Append(T.Substring (T.Length -2 ));
> }
> return sb.ToString();
> }
Don't let the unicode string fool you.
Just wanted to convert a string (with ansi chars) to two-byte hex notation.
Using a string for in and out is simply convienant.
The VB part has an Hex() function, c has value converters.

"George Ter-Saakov" <gt-nsp@.cardone.com> schreef in bericht
news:uOEDc89MGHA.1028@.TK2MSFTNGP11.phx.gbl...
> Sorry, did not understand from your code what is this function suppose to
> do.
> Please tell us what you want to get out of the function with name
> StringToHex
>
> George.
> "Edwin Knoppert" <news@.hellobasic.com> wrote in message
> news:43f5dbbb$0$2025$ba620dc5@.text.nova.planet.nl. ..
>> public static String StringToHex(String sString)
>> {
>> if (sString.Length == 0) { return ""; }
>> StringBuilder sb = new StringBuilder(sString.Length * 2);
>> Char[] chars = sString.ToCharArray();
>> String T = "";
>> foreach (Char c in chars)
>> {
>> T = "0" + Convert.ToString(c, 16).ToUpper();
>> sb.Append(T.Substring (T.Length -2 ));
>> }
>> return sb.ToString();
>> }
>>

Monday, March 26, 2012

This could be shorter tight? (String to Hex)

public static String StringToHex(String sString)
{
if (sString.Length == 0) { return ""; }
StringBuilder sb = new StringBuilder(sString.Length * 2);
Char[] chars = sString.ToCharArray();
String T = "";
foreach (Char c in chars)
{
T = "0" + Convert.ToString(c, 16).ToUpper();
sb.Append(T.Substring (T.Length -2 ));
}
return sb.ToString();
}Sorry, did not understand from your code what is this function suppose to
do.
Please tell us what you want to get out of the function with name
StringToHex
George.
"Edwin Knoppert" <news@.hellobasic.com> wrote in message
news:43f5dbbb$0$2025$ba620dc5@.text.nova.planet.nl...
> public static String StringToHex(String sString)
> {
> if (sString.Length == 0) { return ""; }
> StringBuilder sb = new StringBuilder(sString.Length * 2);
> Char[] chars = sString.ToCharArray();
> String T = "";
> foreach (Char c in chars)
> {
> T = "0" + Convert.ToString(c, 16).ToUpper();
> sb.Append(T.Substring (T.Length -2 ));
> }
> return sb.ToString();
> }
>
Don't let the unicode string fool you.
Just wanted to convert a string (with ansi chars) to two-byte hex notation.
Using a string for in and out is simply convienant.
The VB part has an Hex() function, c has value converters.
"George Ter-Saakov" <gt-nsp@.cardone.com> schreef in bericht
news:uOEDc89MGHA.1028@.TK2MSFTNGP11.phx.gbl...
> Sorry, did not understand from your code what is this function suppose to
> do.
> Please tell us what you want to get out of the function with name
> StringToHex
>
> George.
> "Edwin Knoppert" <news@.hellobasic.com> wrote in message
> news:43f5dbbb$0$2025$ba620dc5@.text.nova.planet.nl...
>

Tuesday, March 13, 2012

thread safety

Hi,
I have a web app which has the following design to get to the DB
Web Page (uses)
-> .net DLL library
--> has a class with static methods
--> static method to-do basic DB operations like create a
DataReader for given sql, get Dataset etc
Big question is... Is this design safe when a lot of users are hitting the
web site from the asp.net threading perspective?As long as the static methods dont access static fields or properties then i
t
should be thread safe.
Ciaran O''Donnell
http://wannabedeveloper.space.live.com
"tjain" wrote:

> Hi,
> I have a web app which has the following design to get to the DB
> Web Page (uses)
> -> .net DLL library
> --> has a class with static methods
> --> static method to-do basic DB operations like create a
> DataReader for given sql, get Dataset etc
> Big question is... Is this design safe when a lot of users are hitting th
e
> web site from the asp.net threading perspective?
>

Thread safety advice

My application uses a singleton static class for writing entries to a log
file. The location and name of the log-file is read from web.config each time
an entry is written, but has the current date inserted into its name. For
example, the string:

c:\inetpub\wwwroot\myapp\log.txt

will be changed to:

c:\inetpub\wwwroot\myapp\log_20060216.txt

However, as we have many concurrent users on the site at once, each
generating hundreds of log file entries a minute, we're finding that multiple
threads are calling the same code at the same time and we're getting filename
with multiple date stamps. Ie:

c:\inetpub\wwwroot\myapp\log_20060216_20060216.txt

I'm sure this is to do with the following code not being thread-safe despite
the "lock" critical section statement:

string sLog_File_Path = ConfigurationManager.AppSettings["logfilepath"];

lock (FoLockObject) {
sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path) ,
Path.GetFileNameWithoutExtension(sLog_File_Path) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(sLog_File_Path));
}

Can anyone offer advice on the correct way to protect code that is
vulnerable to threading issues. I'm aware of synchronization objects such as
Mutex's but am unsure how to use them with static classes. A stright forward
example in C# without being too clever would be very handy

Thanks

BenIs sLog_File_Path local or member variable?
What about FoLockObject?

Unfortunately it' hard to say where is the problem you need to show us full
class.

George.

"Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
> My application uses a singleton static class for writing entries to a log
> file. The location and name of the log-file is read from web.config each
> time
> an entry is written, but has the current date inserted into its name. For
> example, the string:
> c:\inetpub\wwwroot\myapp\log.txt
> will be changed to:
> c:\inetpub\wwwroot\myapp\log_20060216.txt
> However, as we have many concurrent users on the site at once, each
> generating hundreds of log file entries a minute, we're finding that
> multiple
> threads are calling the same code at the same time and we're getting
> filename
> with multiple date stamps. Ie:
> c:\inetpub\wwwroot\myapp\log_20060216_20060216.txt
> I'm sure this is to do with the following code not being thread-safe
> despite
> the "lock" critical section statement:
> string sLog_File_Path = ConfigurationManager.AppSettings["logfilepath"];
> lock (FoLockObject) {
> sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path) ,
> Path.GetFileNameWithoutExtension(sLog_File_Path) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(sLog_File_Path));
> }
> Can anyone offer advice on the correct way to protect code that is
> vulnerable to threading issues. I'm aware of synchronization objects such
> as
> Mutex's but am unsure how to use them with static classes. A stright
> forward
> example in C# without being too clever would be very handy
> Thanks
> Ben
Here's an abbreviated version of the full class.

public class CLog {
private static string FsLog_File_Path = "";
private static object FoLockObject = new object();

private static void RefreshSettings() {
FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];

lock (FoLockObject) {
FsLog_File_Path =
Path.Combine(Path.GetDirectoryName(FsLog_File_Path ),
Path.GetFileNameWithoutExtension(FsLog_File_Path) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(FsLog_File_Path));
}
}

public static void WriteInfo(string sDescription) {
RefreshSettings();

StreamWriter oStream = null;

try {
if (File.Exists(FsLog_File_Path)) {
oStream = File.AppendText(FsLog_File_Path);
}
else {
oStream = File.CreateText(FsLog_File_Path);
}

oStream.AutoFlush = true;

string sSession = "";
if (HttpContext.Current != null) sSession =
HttpContext.Current.Session.SessionID + " - ";
else sSession = "";

oStream.WriteLine(string.Format("{0} - {1} - {2}{3}",
DateTime.Now.ToString("dd MMM yyy H:mm:ss"), "INFO", sSession,
sDescription));
}
catch (IOException) {

}
finally {
if (oStream != null) oStream.Close();
oStream = null;
}
}
}

"George Ter-Saakov" wrote:

> Is sLog_File_Path local or member variable?
> What about FoLockObject?
> Unfortunately it' hard to say where is the problem you need to show us full
> class.
> George.
>
> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
> news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
> > My application uses a singleton static class for writing entries to a log
> > file. The location and name of the log-file is read from web.config each
> > time
> > an entry is written, but has the current date inserted into its name. For
> > example, the string:
> > c:\inetpub\wwwroot\myapp\log.txt
> > will be changed to:
> > c:\inetpub\wwwroot\myapp\log_20060216.txt
> > However, as we have many concurrent users on the site at once, each
> > generating hundreds of log file entries a minute, we're finding that
> > multiple
> > threads are calling the same code at the same time and we're getting
> > filename
> > with multiple date stamps. Ie:
> > c:\inetpub\wwwroot\myapp\log_20060216_20060216.txt
> > I'm sure this is to do with the following code not being thread-safe
> > despite
> > the "lock" critical section statement:
> > string sLog_File_Path = ConfigurationManager.AppSettings["logfilepath"];
> > lock (FoLockObject) {
> > sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path) ,
> > Path.GetFileNameWithoutExtension(sLog_File_Path) + "_" +
> > DateTime.Now.ToString("yyyyMMdd") +
> > Path.GetExtension(sLog_File_Path));
> > }
> > Can anyone offer advice on the correct way to protect code that is
> > vulnerable to threading issues. I'm aware of synchronization objects such
> > as
> > Mutex's but am unsure how to use them with static classes. A stright
> > forward
> > example in C# without being too clever would be very handy
> > Thanks
> > Ben
>
You do have a problem in your code.
This line is not thread safe.

FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];

You are modifying the variable while some other thread could have been doing
the code that is in lock {} section.
So move that line inside (but read further)

---------------
I am not sure why your are doing it this way. Because I do not see any gain
in FsLog_File_Path beign global/member variable.
I would rewrite the code to avoid any synchronization

private static void RefreshSettings() {
string sPath =
ConfigurationSettings.AppSettings["logfilepath"];
sPath = Path.Combine(Path.GetDirectoryName(sPath),
Path.GetFileNameWithoutExtension(sPath) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(sPath));
}
}

As you can see all manipulations are made to local variable so you do not
need lock.

--------------------

The only place where you will need to lock is where you are opening the file
and writing to it. Since that is not thread safe.
And this will fail if you try to open/write into file from multiple threads.

George

"Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
news:B6D5463F-61F6-41BB-B39D-7679E2587C0A@.microsoft.com...
> Here's an abbreviated version of the full class.
> public class CLog {
> private static string FsLog_File_Path = "";
> private static object FoLockObject = new object();
> private static void RefreshSettings() {
> FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
> lock (FoLockObject) {
> FsLog_File_Path =
> Path.Combine(Path.GetDirectoryName(FsLog_File_Path ),
> Path.GetFileNameWithoutExtension(FsLog_File_Path) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(FsLog_File_Path));
> }
> }
> public static void WriteInfo(string sDescription) {
> RefreshSettings();
> StreamWriter oStream = null;
> try {
> if (File.Exists(FsLog_File_Path)) {
> oStream = File.AppendText(FsLog_File_Path);
> }
> else {
> oStream = File.CreateText(FsLog_File_Path);
> }
> oStream.AutoFlush = true;
> string sSession = "";
> if (HttpContext.Current != null) sSession =
> HttpContext.Current.Session.SessionID + " - ";
> else sSession = "";
>
> oStream.WriteLine(string.Format("{0} - {1} - {2}{3}",
> DateTime.Now.ToString("dd MMM yyy H:mm:ss"), "INFO", sSession,
> sDescription));
> }
> catch (IOException) {
> }
> finally {
> if (oStream != null) oStream.Close();
> oStream = null;
> }
> }
> }
> "George Ter-Saakov" wrote:
>> Is sLog_File_Path local or member variable?
>> What about FoLockObject?
>>
>> Unfortunately it' hard to say where is the problem you need to show us
>> full
>> class.
>>
>> George.
>>
>>
>> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
>> news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
>> > My application uses a singleton static class for writing entries to a
>> > log
>> > file. The location and name of the log-file is read from web.config
>> > each
>> > time
>> > an entry is written, but has the current date inserted into its name.
>> > For
>> > example, the string:
>>> > c:\inetpub\wwwroot\myapp\log.txt
>>> > will be changed to:
>>> > c:\inetpub\wwwroot\myapp\log_20060216.txt
>>> > However, as we have many concurrent users on the site at once, each
>> > generating hundreds of log file entries a minute, we're finding that
>> > multiple
>> > threads are calling the same code at the same time and we're getting
>> > filename
>> > with multiple date stamps. Ie:
>>> > c:\inetpub\wwwroot\myapp\log_20060216_20060216.txt
>>> > I'm sure this is to do with the following code not being thread-safe
>> > despite
>> > the "lock" critical section statement:
>>> > string sLog_File_Path =
>> > ConfigurationManager.AppSettings["logfilepath"];
>>> > lock (FoLockObject) {
>> > sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path) ,
>> > Path.GetFileNameWithoutExtension(sLog_File_Path) + "_" +
>> > DateTime.Now.ToString("yyyyMMdd") +
>> > Path.GetExtension(sLog_File_Path));
>> > }
>>> > Can anyone offer advice on the correct way to protect code that is
>> > vulnerable to threading issues. I'm aware of synchronization objects
>> > such
>> > as
>> > Mutex's but am unsure how to use them with static classes. A stright
>> > forward
>> > example in C# without being too clever would be very handy
>>> > Thanks
>>> > Ben
>>>
>>
>
Hi George,

I see the error of my ways and have changed it as you suggested. This was
basically a quick hack to include the date in the filename, as this wasn't
the origianl intention.

Thanks for the advice

Ben

"George Ter-Saakov" <gt-nsp@.cardone.com> wrote in message
news:OOv8TCwMGHA.3732@.TK2MSFTNGP10.phx.gbl...
> You do have a problem in your code.
> This line is not thread safe.
> FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
> You are modifying the variable while some other thread could have been
> doing the code that is in lock {} section.
> So move that line inside (but read further)
> ---------------
> I am not sure why your are doing it this way. Because I do not see any
> gain in FsLog_File_Path beign global/member variable.
> I would rewrite the code to avoid any synchronization
> private static void RefreshSettings() {
> string sPath =
> ConfigurationSettings.AppSettings["logfilepath"];
> sPath = Path.Combine(Path.GetDirectoryName(sPath),
> Path.GetFileNameWithoutExtension(sPath) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(sPath));
> }
> }
>
> As you can see all manipulations are made to local variable so you do not
> need lock.
> --------------------
> The only place where you will need to lock is where you are opening the
> file and writing to it. Since that is not thread safe.
> And this will fail if you try to open/write into file from multiple
> threads.
> George
>
> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
> news:B6D5463F-61F6-41BB-B39D-7679E2587C0A@.microsoft.com...
>> Here's an abbreviated version of the full class.
>>
>> public class CLog {
>> private static string FsLog_File_Path = "";
>> private static object FoLockObject = new object();
>>
>> private static void RefreshSettings() {
>> FsLog_File_Path =
>> ConfigurationSettings.AppSettings["logfilepath"];
>>
>> lock (FoLockObject) {
>> FsLog_File_Path =
>> Path.Combine(Path.GetDirectoryName(FsLog_File_Path ),
>> Path.GetFileNameWithoutExtension(FsLog_File_Path) + "_" +
>> DateTime.Now.ToString("yyyyMMdd") +
>> Path.GetExtension(FsLog_File_Path));
>> }
>> }
>>
>> public static void WriteInfo(string sDescription) {
>> RefreshSettings();
>>
>> StreamWriter oStream = null;
>>
>> try {
>> if (File.Exists(FsLog_File_Path)) {
>> oStream = File.AppendText(FsLog_File_Path);
>> }
>> else {
>> oStream = File.CreateText(FsLog_File_Path);
>> }
>>
>> oStream.AutoFlush = true;
>>
>> string sSession = "";
>> if (HttpContext.Current != null) sSession =
>> HttpContext.Current.Session.SessionID + " - ";
>> else sSession = "";
>>
>>
>> oStream.WriteLine(string.Format("{0} - {1} - {2}{3}",
>> DateTime.Now.ToString("dd MMM yyy H:mm:ss"), "INFO", sSession,
>> sDescription));
>> }
>> catch (IOException) {
>>
>> }
>> finally {
>> if (oStream != null) oStream.Close();
>> oStream = null;
>> }
>> }
>> }
>>
>> "George Ter-Saakov" wrote:
>>
>>> Is sLog_File_Path local or member variable?
>>> What about FoLockObject?
>>>
>>> Unfortunately it' hard to say where is the problem you need to show us
>>> full
>>> class.
>>>
>>> George.
>>>
>>>
>>> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
>>> news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
>>> > My application uses a singleton static class for writing entries to a
>>> > log
>>> > file. The location and name of the log-file is read from web.config
>>> > each
>>> > time
>>> > an entry is written, but has the current date inserted into its name.
>>> > For
>>> > example, the string:
>>>>> > c:\inetpub\wwwroot\myapp\log.txt
>>>>> > will be changed to:
>>>>> > c:\inetpub\wwwroot\myapp\log_20060216.txt
>>>>> > However, as we have many concurrent users on the site at once, each
>>> > generating hundreds of log file entries a minute, we're finding that
>>> > multiple
>>> > threads are calling the same code at the same time and we're getting
>>> > filename
>>> > with multiple date stamps. Ie:
>>>>> > c:\inetpub\wwwroot\myapp\log_20060216_20060216.txt
>>>>> > I'm sure this is to do with the following code not being thread-safe
>>> > despite
>>> > the "lock" critical section statement:
>>>>> > string sLog_File_Path =
>>> > ConfigurationManager.AppSettings["logfilepath"];
>>>>> > lock (FoLockObject) {
>>> > sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path) ,
>>> > Path.GetFileNameWithoutExtension(sLog_File_Path) + "_" +
>>> > DateTime.Now.ToString("yyyyMMdd") +
>>> > Path.GetExtension(sLog_File_Path));
>>> > }
>>>>> > Can anyone offer advice on the correct way to protect code that is
>>> > vulnerable to threading issues. I'm aware of synchronization objects
>>> > such
>>> > as
>>> > Mutex's but am unsure how to use them with static classes. A stright
>>> > forward
>>> > example in C# without being too clever would be very handy
>>>>> > Thanks
>>>>> > Ben
>>>>>
>>>
>>>

Thread safety advice

My application uses a singleton static class for writing entries to a log
file. The location and name of the log-file is read from web.config each tim
e
an entry is written, but has the current date inserted into its name. For
example, the string:
c:\inetpub\wwwroot\myapp\log.txt
will be changed to:
c:\inetpub\wwwroot\myapp\log_20060216.txt
However, as we have many concurrent users on the site at once, each
generating hundreds of log file entries a minute, we're finding that multipl
e
threads are calling the same code at the same time and we're getting filenam
e
with multiple date stamps. Ie:
c:\inetpub\wwwroot\myapp\log_20060216_20
060216.txt
I'm sure this is to do with the following code not being thread-safe despite
the "lock" critical section statement:
string sLog_File_Path = ConfigurationManager.AppSettings["logfilepath"];
lock (FoLockObject) {
sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path),
Path. GetFileNameWithoutExtension(sLog_File_Pa
th) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(sLog_File_Path));
}
Can anyone offer advice on the correct way to protect code that is
vulnerable to threading issues. I'm aware of synchronization objects such as
Mutex's but am unsure how to use them with static classes. A stright forward
example in C# without being too clever would be very handy
Thanks
BenIs sLog_File_Path local or member variable?
What about FoLockObject?
Unfortunately it' hard to say where is the problem you need to show us full
class.
George.
"Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
> My application uses a singleton static class for writing entries to a log
> file. The location and name of the log-file is read from web.config each
> time
> an entry is written, but has the current date inserted into its name. For
> example, the string:
> c:\inetpub\wwwroot\myapp\log.txt
> will be changed to:
> c:\inetpub\wwwroot\myapp\log_20060216.txt
> However, as we have many concurrent users on the site at once, each
> generating hundreds of log file entries a minute, we're finding that
> multiple
> threads are calling the same code at the same time and we're getting
> filename
> with multiple date stamps. Ie:
> c:\inetpub\wwwroot\myapp\log_20060216_20
060216.txt
> I'm sure this is to do with the following code not being thread-safe
> despite
> the "lock" critical section statement:
> string sLog_File_Path = ConfigurationManager.AppSettings["logfilepath"];
> lock (FoLockObject) {
> sLog_File_Path = Path.Combine(Path.GetDirectoryName(sLog_File_Path),
> Path. GetFileNameWithoutExtension(sLog_File_Pa
th) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(sLog_File_Path));
> }
> Can anyone offer advice on the correct way to protect code that is
> vulnerable to threading issues. I'm aware of synchronization objects such
> as
> Mutex's but am unsure how to use them with static classes. A stright
> forward
> example in C# without being too clever would be very handy
> Thanks
> Ben
>
Here's an abbreviated version of the full class.
public class CLog {
private static string FsLog_File_Path = "";
private static object FoLockObject = new object();
private static void RefreshSettings() {
FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
lock (FoLockObject) {
FsLog_File_Path =
Path.Combine(Path.GetDirectoryName(FsLog_File_Path),
Path. GetFileNameWithoutExtension(FsLog_File_P
ath) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(FsLog_File_Path));
}
}
public static void WriteInfo(string sDescription) {
RefreshSettings();
StreamWriter oStream = null;
try {
if (File.Exists(FsLog_File_Path)) {
oStream = File.AppendText(FsLog_File_Path);
}
else {
oStream = File.CreateText(FsLog_File_Path);
}
oStream.AutoFlush = true;
string sSession = "";
if (HttpContext.Current != null) sSession =
HttpContext.Current.Session.SessionID + " - ";
else sSession = "";
oStream.WriteLine(string.Format("{0} - {1} - {2}{3}",
DateTime.Now.ToString("dd MMM yyy H:mm:ss"), "INFO", sSession,
sDescription));
}
catch (IOException) {
}
finally {
if (oStream != null) oStream.Close();
oStream = null;
}
}
}
"George Ter-Saakov" wrote:

> Is sLog_File_Path local or member variable?
> What about FoLockObject?
> Unfortunately it' hard to say where is the problem you need to show us fu
ll
> class.
> George.
>
> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
> news:27A2FF7B-4565-40A5-8D95-CE197DE94166@.microsoft.com...
>
>
You do have a problem in your code.
This line is not thread safe.
FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
You are modifying the variable while some other thread could have been doing
the code that is in lock {} section.
So move that line inside (but read further)
---
I am not sure why your are doing it this way. Because I do not see any gain
in FsLog_File_Path beign global/member variable.
I would rewrite the code to avoid any synchronization
private static void RefreshSettings() {
string sPath =
ConfigurationSettings.AppSettings["logfilepath"];
sPath = Path.Combine(Path.GetDirectoryName(sPath),
Path.GetFileNameWithoutExtension(sPath) + "_" +
DateTime.Now.ToString("yyyyMMdd") +
Path.GetExtension(sPath));
}
}
As you can see all manipulations are made to local variable so you do not
need lock.
----
The only place where you will need to lock is where you are opening the file
and writing to it. Since that is not thread safe.
And this will fail if you try to open/write into file from multiple threads.
George
"Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
news:B6D5463F-61F6-41BB-B39D-7679E2587C0A@.microsoft.com...
> Here's an abbreviated version of the full class.
> public class CLog {
> private static string FsLog_File_Path = "";
> private static object FoLockObject = new object();
> private static void RefreshSettings() {
> FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
> lock (FoLockObject) {
> FsLog_File_Path =
> Path.Combine(Path.GetDirectoryName(FsLog_File_Path),
> Path. GetFileNameWithoutExtension(FsLog_File_P
ath) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(FsLog_File_Path));
> }
> }
> public static void WriteInfo(string sDescription) {
> RefreshSettings();
> StreamWriter oStream = null;
> try {
> if (File.Exists(FsLog_File_Path)) {
> oStream = File.AppendText(FsLog_File_Path);
> }
> else {
> oStream = File.CreateText(FsLog_File_Path);
> }
> oStream.AutoFlush = true;
> string sSession = "";
> if (HttpContext.Current != null) sSession =
> HttpContext.Current.Session.SessionID + " - ";
> else sSession = "";
>
> oStream.WriteLine(string.Format("{0} - {1} - {2}{3}",
> DateTime.Now.ToString("dd MMM yyy H:mm:ss"), "INFO", sSession,
> sDescription));
> }
> catch (IOException) {
> }
> finally {
> if (oStream != null) oStream.Close();
> oStream = null;
> }
> }
> }
> "George Ter-Saakov" wrote:
>
Hi George,
I see the error of my ways and have changed it as you suggested. This was
basically a quick hack to include the date in the filename, as this wasn't
the origianl intention.
Thanks for the advice
Ben
"George Ter-Saakov" <gt-nsp@.cardone.com> wrote in message
news:OOv8TCwMGHA.3732@.TK2MSFTNGP10.phx.gbl...
> You do have a problem in your code.
> This line is not thread safe.
> FsLog_File_Path = ConfigurationSettings.AppSettings["logfilepath"];
> You are modifying the variable while some other thread could have been
> doing the code that is in lock {} section.
> So move that line inside (but read further)
> ---
> I am not sure why your are doing it this way. Because I do not see any
> gain in FsLog_File_Path beign global/member variable.
> I would rewrite the code to avoid any synchronization
> private static void RefreshSettings() {
> string sPath =
> ConfigurationSettings.AppSettings["logfilepath"];
> sPath = Path.Combine(Path.GetDirectoryName(sPath),
> Path.GetFileNameWithoutExtension(sPath) + "_" +
> DateTime.Now.ToString("yyyyMMdd") +
> Path.GetExtension(sPath));
> }
> }
>
> As you can see all manipulations are made to local variable so you do not
> need lock.
> ----
> The only place where you will need to lock is where you are opening the
> file and writing to it. Since that is not thread safe.
> And this will fail if you try to open/write into file from multiple
> threads.
> George
>
> "Ben Fidge" <BenFidge@.discussions.microsoft.com> wrote in message
> news:B6D5463F-61F6-41BB-B39D-7679E2587C0A@.microsoft.com...
>

Thread Safety?

i have an asp.net application which almost all of its methods are static methods.
is it prone for bugs and thread collisions or something?

No. There is nothing like that a static function is prone to bugs or collisions. Firstly, static member functions cannot access non-static members directly. A class member declared with the keywordstatic is a static member. A static member is owned by the class, not by its instances (objects of the class).
Note that static members are actually class members, while non-static members are instance members (means they are owned by the instances). Both in C# & VB.NET, we may create static/shared events, properties, fields and functions.

Due to the independent nature of static functions, it wont be affected by other threads at all.

HTH

Cheers

Vishal Khanna

(pls mark as answer if reply helps)