You may simply put try .. with block inside async expression and handle it there.

By on 3/24/2009 8:08 AM ()

I guess I haven't been really clear, so I'm posting the full function.
The try/catch is already inside the async...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let private WriteBytes (destStream:FileStream) (url:string) (startPos:int) endPos =
	async{
		let req = WebRequest.Create(url) :?>  HttpWebRequest
		req.AllowAutoRedirect <- true
		req.KeepAlive <- false
		if endPos <> 0 then
			req.AddRange(startPos, endPos)
		req.CookieContainer <- CookieContainer
		try
			let resp = lock CookieContainer (fun() -> req.GetResponse() :?> HttpWebResponse)
			use stream = resp.GetResponseStream()
			let rec readStream left = 
				async {
					let arr = Array.init 3000 (fun _ -> byte 0)
					let readSize = 
						if 3000 < left then 3000
						else left
					let! actuallyRead = stream.AsyncRead(arr, 0, readSize)
					do! destStream.AsyncWrite(arr, 0, actuallyRead)
					if left > actuallyRead then
						do! readStream (left-actuallyRead)
				}
			do! readStream (resp.Headers.["Content-Length"] |> int32)
			destStream.Flush()
			destStream.Close()
			destStream.Dispose()
		with
		| e -> failwith e.Message
	}

Edit: I believe I just found a bug in CommunityServer, as when I try to write inside the quote req.CookieContainer <- CookieContainer the right side of the assignment operator is not displayed.

By on 3/24/2009 10:08 AM ()

Here is my quick guess.

Your try-with is working (can just change req.GetResponse() to something like (raise <| new TimeoutException()) for easy testing). Try putting e.g. a printfn in the 'with' clause to verify.

However the 'calling' code perhaps expects the exception to come from 'WriteBytes'. But this is wrong; WriteBytes never throws, it just returns an Async object - a computation that will be run later e.g. with Async.Run. That's where the exception will 'pop out'.

By on 3/24/2009 10:36 AM ()

I have just found the problem, but I think it's kind of a weird behaviour. Understandable, but weird.

Basically if I put try/catch in the function passed to lock, the exception is caught and can be handled. But if the try/catch is only in the outer function (the one with async) the exception doesn't get caught at all.

I actually don't find it too intuitive...

Is this behaviour by design?

Regards

By on 3/24/2009 11:06 AM ()

Hmm, that definitely should not be happening, and I don't reproduce it with a simple program like

1
2
3
4
5
6
7
8
9
10
open System

let F() =
    let x = "foo"
    try
        lock x (fun() -> raise <| new Exception())
    with 
    | e -> printfn "ex"

F()

Can you reduce this to a small repro?

By on 3/24/2009 11:21 AM ()

The code below suffices to reproduce the issue I'm experiencing. I'd like to point out that I'm using the Sept.2008 CTP, so this affects the latest version available to the public.

In the example, calling HitMe() or HitMe'() will result in the program crashing on "REPRODUCED".

Curiously enough, in this case running without debugging will not break the execution, while in the scenario I had posted before the application broke even if run without debugging and the stack trace was prompted.

1
2
3
4
5
6
7
8
9
10
let private repro (url:string) =
        async{
            try
                lock CookieContainer (fun() -> failwith "REPRODUCED")
            with
            | _ -> failwith "YOU GOT IT RIGHT!"
        }
      
    let HitMe() = Async.Run(Async.Parallel [repro "http://www.google.it"])
    let HitMe'() = Async.Run(repro "http://www.google.it")

Regards

By on 3/24/2009 1:35 PM ()

All I see is expected behavior.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#light
let CookieContainer = "foo"
let private repro (url:string  ) = 
    async{ 
        try 
            lock CookieContainer (fun() -> failwith "REPRODUCED") 
        with 
        | _ -> failwith "YOU GOT IT RIGHT!" 
    } 

let HitMe() = Async.Run(Async.Parallel [repro "http://www.google.it"  ]) 
let HitMe'() = Async.Run(repro "http://www.google.it"  ) 
try
    HitMe() |> ignore
with
    e -> printfn "%s" e.Message
try
    HitMe'()
with
    e -> printfn "%s" e.Message

prints 'you got it right' both times (on my box with the CTP, 1.9.6.2).

There is a bit of talk about the VS experience on the thread; VS has lots of options that interact with this (e.g. 'catch all first chance exceptions', 'just my code', ...) and I wonder if these are interacting with your interpretations of the behavior.

By on 3/24/2009 2:18 PM ()

There is a bit of talk about the VS experience on the thread; VS has lots of options that interact with this (e.g. 'catch all first chance exceptions', 'just my code', ...) and I wonder if these are interacting with your interpretations of the behavior.

It may not be purely a compiler problem, but it is weird that the code I pasted above breaks in the t function as it is, but when you remove either the lazy or the lock (without touching any VS settings) it doesn't break anymore. It seems the OP encountered similar problems.

By on 3/24/2009 3:11 PM ()

Right, while the code I posted only shows a first chance exception, the function I had posted before (it was a full function so although not too handy for tests it can still be verified) ended with the exception not being handled (and yellow-background VS debugger popup as opposed to first chance exceptions with the green background)...

By on 3/24/2009 4:13 PM ()

I've also noted some weirdness with exceptions, closures, lazy and workflows. (e.g. [link:cs.hubfs.net] )What about this:

1
2
3
4
5
6
7
8
9
10
let t = lazy (lock "foo" (fun() -> raise <| new Exception()))

let F() =
    let x = "foo"
    try
       t.Force() 
    with 
    | e -> printfn "ex"

F()

When I run it in debug VS breaks inside the lock, complaining about an unhandled exception. Hitting f5 continues to actually handle the exception.This one could be tricky: without lazy, it doesn't happen. Without lock, it doesn't happen.Kurt

By on 3/24/2009 11:52 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper