Yes, I disagree with your assertion stating the Stream interface is the
wrong abstraction for random access because it already contains a Seek
method.  The random access is already there.

So, for streams where (CanSeek == true) there should also be a
BeginRead/Write(file_offset, ...) which is threadsafe.

Yes, you're right the docs say it isn't threadsafe.  But for heaven sake,
surely we can add a class that is threadsafe for file io in the same way the
Win32 API provides.  How are people supposed to write high throughput server
software without a good async managed file io class?  Apparently everyone is
still using C++.

As you may have guessed, I've already hit this on my current project.  Lots
of locks to compensate for the above oversight.

From: Ian Griffiths <[EMAIL PROTECTED]>
Reply-To: "Discussion of advanced .NET topics."
<[email protected]>
To: [email protected]
Subject: Re: [ADVANCED-DOTNET] Possible defect in BeginWrite on FileStream
Date: Thu, 15 Dec 2005 22:42:36 -0000

John Davis wrote:
> Ian I'm afraid you're really mistaken on this one.

Which bit do you disagree with?

Do you disagree that Stream is the wrong abstraction for random access?

Do you disagree that if a class is documented as not safe for
multi-threaded access, then it doesn't really matter what new methods
you add, you still can't use it from multiple threads?

Do you disagree with the claim that Stream offering stream-like
behaviour is a design limitation and not an actual defect? (The absence
of a random access API might be regarded as a defect, but that doesn't
mean there's necessarily a problem with the stream API - it does what
it's designed to do.)

You've obviously thought long and hard about it - almost 7 months
according to the email timestamps. :)  But I can't tell what I said that
you think I'm "really mistaken on".

I'm not disagreeing that random access (as opposed to stream-like
access) would be nice to have. (Although it's not something I happen to
have run into a need for in any .NET projects yet.) I'm just saying
Stream's the wrong place for it.

In particular, bear in mind that not all Streams are implemented on top
of something that necessarily has intrinsic OVERLAPPED-like
functionality. (Not all streams are files or file-like handles.)



> What I'm looking for is the equivalent of a ReadFile or WriteFile
> call here the offset is passed in the OVERLAPPED struct.

I agree there are circumstances in which this would be handy. But I
stand by my assertions that Stream is the wrong abstraction for this.
Not every Stream is a file. Stream is not meant to be an abstract
representation of a file - it's more widely applicable than that. (Hence
its narrower API - the more specific an API an abstraction has, the less
broadly applicable it is.)


> The call can occur through overlapped IO, or an IO completion
> port.  The call is also atomic.

And it's not presenting a stream-like abstraction.  I think that's at
the heart of the issue.



> There needs to be a random access async read/write of some
> sort which uses the OVERLAPPED struct in the Win32 API in that
> it has a file offset field for the read or write.

Sure, just probably not Stream.

I guess if you changed nature of the Stream API by adding new
non-streamish functionality and also changed the classes so they
permitted concurrent access then that'd solve the problem. (Except for
the fact that this might break a lot of existing streams because they
don't implement this feature right now...)

But aren't you introducing a whole new abstraction?


> If one observes the current implementation in
> DotNetReflector, the OVERLAPPED struct is getting populated
> via the FileStream Seek call.  The OVERLAPPED struct is then
> used on the next async write.  Why implement it this way if
> FileStreams can only be used by a single thread?

Err...isn't that a distinctly sequential approach to the problem? It
presumes that the call to Seek and the async write will follow on one
after the other without interference.

You'd need a completely different implementation if you wanted to
support non-sequential use wouldn't you?


--
Ian Griffiths


On Thu, 26 May 2005 23:22:45 +0100, Ian Griffiths
<[EMAIL PROTECTED]>
wrote:

>Even if there were an atomic method how would that help?  It wouldn't
>eliminate the race condition, because it would still be illegal to call
>the method simultaneously on multiple threads. (FileStream's
>documentation says it's illegal to do that.)  So you'd still need to
use
>locking or some other synchronization method to make sure your threads
>take it in turns even if there were an atomic method.
>
>I agree it would be cleaner to have a random access method if random
>access is what you're doing - a stream isn't really the right
>abstraction in that case.  (Sadly it's the only one we're offered
>AFAIK.)
>
>But is this a defect?  It's a bug to use a stream from multiple threads
>without synchronization.  It would still be a bug even with the atomic
>method you propose.
>
>
>--
>Ian Griffiths
>http://www.interact-sw.co.uk/iangblog/
>
>> -----Original Message-----
>> From: John Davis
>>
>> >Are you saying that locking, Seeking, BeginWriteing, and unlocking
is
>> not good enough?
>>
>> Well, I guess it is good enough, just doesn't seem very elegant.
>Would be
>> nice if there was an offset in there so one "atomic" call could be
>made.
>> Same as with Win32 overlapped io.
>>
>> >Does the BeginWrite not in effect take a snapshot of
>> the seek location when the operation starts?
>>
>> I don't know for certain if it does, I certainly hope so.  Time to go
>> digging with reflector I guess.
>>
>> Ian Griffiths <[EMAIL PROTECTED]> wrote:
>> The documentation says that members of this class are not thread
safe,
>> so multiple threads shouldn't be using this at any given instance.
You
>> need to do some kind of locking if you have multiple threads using
it.
>>
>> Are you saying that locking, Seeking, BeginWriteing, and unlocking is
>> not good enough? Does the BeginWrite not in effect take a snapshot of
>> the seek location when the operation starts?

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to