|
-
It took about two long weeks of headaches... Long night talks with MS Support, frustrated customer, angry CEO... One simple hint in event viewer could save all that, but no, the error (or actually warning) didn't say much, and we had to find it the hard way. Those were the warnings in System event log: A process serving application pool '...' suffered a fatal communication error with the World Wide Web Publishing Service (IIS6) A process serving application pool '...' suffered a fatal communication error with the Windows Process Activation Service (IIS7) It seemed that after that warning, the IIS process just crashed. And we had to find the reason why: <%@Page Language="C#"%>
<script runat='server'>
void Crash()
{
Crash();
}
</script>
<html>
<head><title>Crashing Your IIS</title></head>
<body><%Crash();%></body>
</html>
Yes, it's definitely a bug, but why to crash all the process? Furthermore, isn't it that hard to put 'Stack overflow' error into event log?
|
-
That was the exception I was getting when tried to implement interceptors in Windsor. I had no problem with "doesnt" (I wouldn't write this post because of it), my problem was IMethodInterceptor. It all started from samples I was trying to run. All samples on web clearly showed that I need to implement IMethodInterceptor, but I couldn't find this interface in any of Castle's assemblies... After googling I've realized that the interface now (R3) has a new name: IInterceptor. OK, that's easy - I just replaced the interface name with the new one, the app successfully compiled, but then at runtime I got the above exception... Hmm... I thought I had the old Castle's version installed somewhere - but I didn't... Then I've opened Reflector: protected IInterceptor[] ObtainInterceptors(IKernel kernel, ComponentModel model) { IInterceptor[] interceptorArray = new IInterceptor[model.Interceptors.Count]; int num = 0; /* Omitting the code for clarity... */ try { IInterceptor interceptor = (IInterceptor) handler.Resolve(CreationContext.Empty); interceptorArray[num++] = interceptor; this.SetOnBehalfAware(interceptor as IOnBehalfAware, model); continue; } catch (InvalidCastException) { throw new ApplicationException(string.Format( "An interceptor registered for {0} doesnt implement the IMethodInterceptor interface", model.Name)); } } return interceptorArray; }
Aha, they've just forgot to change the message after changing the name of the interface! (Resharper would help with that :) )
Now it's clear, but still... what's wrong with my code, and why do I get this exception?
After looking at it for a while, I've finally realized what was the problem: There're actually two(!) IInterceptor interfaces: Castle.DynamicProxy.IInterceptor Castle.Core.Interceptor.IInterceptor
And I was using the wrong one :) So, when defining interceptors for Windsor, you need to implement Castle.Core.Interceptor.IInterceptor.
|
-
I've built the development environment using the following link.
It took me two sleepless nights, but eventually it worked! Whew...
This is the first time I'm dealing with Mac and Objective-C; Actually, it wasn't on my must learn list, but it' so cool that I guess I'll just have to spend some time playing with this toy... |  |
|
-
Here's how my blog looks from my new iPhone: Cool! (I mean the iPhone, not the blog)
|
-
Quite often there's just a straightforward implementation for a property: private variable and getter/setter: private int _MyInt;
public int MyInt
{
get
{
return _MyInt;
}
set
{
_MyInt = value;
}
}
In C# Orcas it's possible to express the above code as simple as: public int MyInt { get; set; }
Couple of points:
-
If we would look at generated IL code we would see that internally the (hidden) private variable and appropriate get/set methods are generated (no magic here).
-
Later on it's possible to add a specific implementation for get/set without recompiling client's code (that would be the case if we would move from an instance variable to a property).
|
-
Today I needed to implement an iterator for a custom collection. I remembered the .NET 1.1 (tedious) experience of implementing IEnumerator manually, and was pleasantly surprised that with .NET 2.0 (or actually with C# 2.0) it became much easier (and I'm not talking about Generics support that I would naturally expect anyway): all the boring stuff is created behind the scenes (and now at last I know what this yield keyword does!): class MyCollection:IEnumerable
{
string[] stringArray = new string[]{"A","B","C"};
public IEnumerator GetEnumerator()
{
foreach(string str in stringArray)
{
yield return str;
}
}
}
class Program
{
static void Main()
{
foreach (object x in new MyCollection())
{
Console.WriteLine(x);
}
}
}
So all that's needed is to "collect" the items using yield return statement. It looked like magic at first, but when I've checked the generated IL it contained the implementation of IEnumerator (so compiler generates it for us).
It's important to understand that the GetEnumerator method above is not evaluated in a way that you would normally expect (all because of the yield return), behind the scenes this language structure is "translated" into concrete IEnumerator class implementation with familiar .MoveNext(), .Current, .Reset (which is deprecated now). So for example the following implementation is 100% valid: public IEnumerator GetEnumerator()
{
while(true)
{
yield return new Random().Next();
}
}
There's no infinite loop here, since the values will be "evaluated" one-by-one using .MoveNext() during foreach loop in the calling code (and that foreach loop will actually control the exit criteria).
There's another related statement: yield break. At first I wondered why it is needed: OK, I read documentation that saying that it's needed to tell the client to stop looping, but why would I need a new structure for this? Couldn't I just use a regular return statement? It turns out that I couldn't: the GetEnumerator() returns IEnumerator (which is created behind the scenes), so I can't just use return.
|
-
-
I found no differences between the following two options: It seems just as two different ways to achieve exactly the same thing...
|
-
If the schemas on publisher and subscriber are the essentially the same, but only differ by order of columns: Then when applying a snapshot, if 'Action if name in use' option is set to anything other than 'Drop existing object and create a new one', the BCP will throw 'Field size too large' exception. That's just another "meaningful" replication-related error from Microsoft... So, if you want to use BCP (snapshots) publisher's and subscribers' schemas should be exactly the same.
|
-
When I was trying to reinitialize a subscription I was constantly getting a "PK violation error" on one of the tables. At first I thought there was a problem with that specific table: I suspected that "Unique key" join option for that table was wrong, but the error was still there when I unchecked the "Unique key" option. When I removed the PK for that table on a subscriber, the synchronization failed with the same PK violation error but for another table... After exploring it a bit more I've found that the problem was related to "Action if name in use" option: if "Keep existing objects unchanged" is selected, during the synchronization process already existing rows are rewritten into a subscribers' table - which causes PK violation. So with that option, there's actually no way to reinitialize a subscription (I would actually expect a meaningful warning in that case... - and not just PK violation error). So, when I selected "Truncate data..." option, the PK error disappeared and sync finished OK.
|
-
I didn't use Photoshop (well... in fact I did, but only to hide the real DB/Servers details): 
|
-
I've received a new requirement: publisher and subscriber should use different sets of triggers (for a specific table). I thought it wouldn't be a problem: I remembered that there was an option to 'Copy user triggers', so I just needed to set it to 'False': But, for some reason the triggers at a subscriber were always deleted after synchronization... Then I've noticed another option: 'Action if name is in use': The default value for the above option is 'Drop existing object and create a new one'', and that explains why the triggers at subscriber disappear: they're deleted since the table is dropped and recreated. Previously publisher's triggers were copied to the subscriber, but now after I've changed the 'Copy user triggers' option it doesn't happen anymore. So, I just needed to avoid that Drop option (any other option should leave the subscriber's triggers intact). But, when I fixed that and tried to synchronize I've got the following error: {call sp_MSsetconflicttable
(N'table3',
N'MSmerge_conflict_MyTestPublication_table3',
N'VLADIMIR',
N'TestDB',
N'MyTestPublication')}
... Incorrect syntax near 'id':
Incorrect syntax? Syntax error in Microsoft's internal procedure? What have I done wrong?
At least I had a problematic table name. After looking at the table schema both on publisher and subscriber I've noticed that rowguid column (which tracks merge replication changes) was missing from subscriber's schema: (in my case the subscriber's schema is generated offline, not through initial sync from publisher; so there was a bug in that script). Well, I would expect an error in this case, but something more informative than 'Incorrect syntax near...'.
|
-
Here's the situation: I have a table without a primary key (or any other unique constraint). Don't ask me why, since I have no control over the database in this case. To make it even worse, there's a business-logic bug that inserts identical rows in that table (all columns have identical values). OK you fix the bug, but how do you cleanup the table not to contain those duplicate rows? It's not that easy as it sounds at first... Here's the concrete example: create table TableWithoutPK(col1 int, col2 int, col3 char(10))
insert into TableWithoutPK values (1, 1, 'ABC')
insert into TableWithoutPK values (1, 1, 'ABC')
I've tried to use my own SQL knowledge to resolve this puzzle, but with no much success. So I've started googling: at first I've found this KB article, but it seemed too cumbersome. Actually, I was going in that direction, but creating temporary tables and detailing every column for GROUP BY clause was not something I wanted to do; I was looking for a more generic solution. And then in one of the forums (unfortunately now I can't find the original one... otherwise I would share the link) I saw how people are using OVER TSQL Clause (which is new in SQL2005), and that brought me to a more elegant solution: DELETE tmp FROM (
SELECT ROW_NUMBER()
OVER (ORDER BY col1) AS rownum
FROM TableWithoutPK
) AS tmp WHERE rownum > 1
So, at last Oracle's rownum cousin is available in MSS as well! (and at last paging functionality could be properly implemented with MSS - but that's already a different story).
|
-
Here's a good example of bad error handling: 
|
-
I've just found a cool feature in Visual Studio Class Diagram designer that I wasn't aware of: I didn't know that there's a way to represent a composition relationship (HAS-A) in the diagram! More than once I felt it was missing, but instead of looking under my nose I've always returned to Visio to draw my class diagrams. So if we have the following class structure (here I'm using fields just to be concise - but the same works for properties as well): class Blog { List<Post> _Posts; } class Post { Blog _Blog; List<Comment> _Comments; } class Comment { Post _Post; } In the class diagram it looks like this:  And all that's needed is to define per Field/Property to show it as a(Collection) Association.  Cool :)
|
More Posts Next page »
|
|
|