F # Async.FromBeginНе ловить исключения - PullRequest
4 голосов
/ 04 января 2012

Мне трудно понять, почему следующий код не улавливает исключение. Это мой первый опыт использования Async в F #, поэтому я уверен, что это что-то простое

open System
open Microsoft.WindowsAzure
open Microsoft.WindowsAzure.StorageClient
open System.Windows.Forms

let mutable connection = "UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler"

CloudStorageAccount.SetConfigurationSettingPublisher(fun cName cPublisher ->
                                                      cPublisher.Invoke connection |> ignore)

let storageAccount = CloudStorageAccount.Parse connection

let createTable tableName =
        let client = storageAccount.CreateCloudTableClient()
        async{
            try
                do! Async.FromBeginEnd(tableName, client.BeginCreateTable , client.EndCreateTable)
                MessageBox.Show "Created" |>ignore
            with 
            | :? StorageClientException -> printfn "failed"; MessageBox.Show("failed to create table") |> ignore
            | _ -> printfn "Failed with unknown exception"
        } |> Async.Start

[<EntryPoint; STAThread>]
let main(args) =
    let form = new Form()
    let btn = new Button(Text = "Click")
    btn.Click.AddHandler(fun _ _ -> createTable "SomeNewTable")
    form.Controls.Add btn
    let result = form.ShowDialog()
    0

Если я запускаю это, и таблица уже создана, она говорит, что исключение типа StorageClientException не было обработано в коде, в частности, указание на client.EndCreateTable часть вызова FromBeginEnd

Ответы [ 3 ]

4 голосов
/ 06 января 2012

Это пахнет как проблема, которая была исправлена ​​в FSharp.Core в VS2010 SP1..NET SynchronizationContext изменили свое поведение (я думаю, что в .NET 4.0 SP1), и нам потребовалось соответствующее изменение времени выполнения F # для асинхронных операций, чтобы должным образом справиться с привязкой потоков.можете взять более новый FSharp.Core здесь: http://www.microsoft.com/download/en/details.aspx?DisplayLang=en&id=15834

2 голосов
/ 06 марта 2012

Благодаря Дону Сайму, решение состоит в том, чтобы отключить отладку "Просто мой код".Отладка -> Параметры и настройки -> Общие -> снимите флажок «Включить только мой код (только для управляемого)»

Это по-прежнему проблема с бета-версией Visual Studio 11, которая вышла с предварительным просмотром для Windows 8.

2 голосов
/ 04 января 2012

Если причиной исключения является то, что таблица уже существует, почему бы не использовать BeginCreateTableIfNotExist / EndCreateTableIfNotExist.

ОБНОВЛЕНИЕ:

Эта ошибка не имеет ничего общего с Windows Azure.Я могу воспроизвести то же поведение с помощью простой программы:

open System
open System.Windows.Forms

let bufferData = Array.zeroCreate<byte> 100000000

let async1 filename =        
    async{
        try 
            use outputFile = System.IO.File.Create(filename)
            do! outputFile.AsyncWrite(bufferData)   
            MessageBox.Show("OK") |> ignore         
        with 
        | :? ArgumentException -> printfn "Failed with ArgumentException"; MessageBox.Show("Failed with ArgumentException") |> ignore         
        | _ -> printfn "Failed with unknown exception"; MessageBox.Show("Failed with unknown exception") |> ignore         
    } |> Async.Start

let main(args) =
    let form = new Form(Text = "Test Form")
    let button1 = new Button(Text = "Start")
    let button2 = new Button(Text = "Start Invalid", Top = button1.Height + 10)        
    form.Controls.AddRange [| button1; button2; |]
    button1.Click.Add(fun args -> async1 "longoutput.dat")
    // Try an invalid filename to test the error case.
    button2.Click.Add(fun args -> async1 "|invalid.dat")    
    let result = form.ShowDialog()
    0

let _ = main([||])

Странно то, что код отлично работает в F # Interactive, но не может перехватывать исключения при отладке в виде приложения Windows в VisualStudio (не имеет значения отладочная или релизная конфигурация).Даже странно, что он снова работает нормально, если выполняется как приложение за пределами Visual Studio.

Если вам интересно, эта программа адаптирована из примера MSDN , в котором обнаружена та же проблема..

ОБНОВЛЕНИЕ 2:

Аналогичный вопрос был задан на http://cs.hubfs.net/topic/Some/0/59516. Как отметили @ildjarn и @Brian, эта ошибка была исправлена ​​вVS2010 SP1.Без VS2010 SP1 вы также можете протестировать свой код с помощью F # Interactive и без проблем выполнить приложение за пределами VS.

...