I have a filehandler class that moves an xdoument to cache using a lock. Psuedo code:
public FetchDocument() {
var xdoc = Cache[_Key1];
if (xdoc == null) {
lock(_lockobject) {
// in case prev.thread has done upload will currth read waiting
xdoc = Cache[_Key1];
if (xdoc == null) {
开发者_JS百科 .... Code to grab from file and add to catch - works great.....
}
}
}
xdoc = Cache[_Key1];
}
Now I want to expose and event that fires after the file has been loaded but before its cached and which has an abort flag on the event.
The problem is how do I only fire the event(s) for the Current (unlocked) thread only?
an other thread may be locked waiting for this thread to clear the locking code
Thanks
Martin
If I understand correctly, you wish to allow the caller to abort caching the document. You can achieve this by passing a Func into your FetchDocument method, e.g.:
public XDocument FetchDocument(FUnc<XDocument, bool> cacheNewDocument) {
var xdoc;
lock(_lockobject) {
// in case prev.thread has done upload will currth read waiting
xdoc = Cache[_Key1];
if (xdoc == null) {
xdoc = .... Code to grab from file and add to catch - works great.....
if (cacheNewDocument(xdoc)){
Cache.Add(_Key1, xdoc)
}
else{
return xdoc;
}
}
}
return xdoc;
}
In this way your code can call the Func with relevant data before adding the document to the cache and the caller can return true\false to get your abort semantics.
This is much more straightforward than using an event, and enforces the "how do I only fire the event(s) for the Current (unlocked) thread only" semantics.
On another note, although your original code is pseudo code, you are accessing the Cache object outside the lock. Even though these unlocked operations are read operations, the collection could be being mutated inside the lock and so you could get unpredictable results. All operations on the cache should be done in the lock.
All events are processed by the current thread, the problem arises if any of your eventhandlers tries to invoke the UI thread or take another lock.
In that case Monitor.TryEnter
might help in those event handlers.
But the best would be to break up your lock into two locks, one before and one after the event.
精彩评论