WinForms 应用程序中的 F# 跨线程 UI 异常

2023-12-12

我在使用 F# 开发一个简单的应用程序时遇到问题,该应用程序仅读取所请求的 HTML 页面的长度。

当您开发 UI 应用程序时,VB.NET/C# 语言似乎也会出现类似的错误。

enter image description here

但我对 F# 相当陌生,并不真正想象在 F# 中精确解决此类问题的热度。

F# 中的源代码:

http://pastebin.com/e6WM0Sjw

open System
open System.Net
open Microsoft.FSharp.Control.WebExtensions
open System.Windows.Forms

let form = new Form()
let text = new Label()
let button = new Button()

let urlList = [ "Microsoft.com", "http://www.microsoft.com/" 
                "MSDN", "http://msdn.microsoft.com/" 
                "Bing", "http://www.bing.com"
              ]

let fetchAsync(name, url:string) =
    async { 
        try 
            let uri = new System.Uri(url)
            let webClient = new WebClient()
            let! html = webClient.AsyncDownloadString(uri)
            text.Text <- String.Format("Read %d characters for %s", html.Length, name)
        with
            | ex -> printfn "%s" (ex.Message);
    }

let runAll() =
    urlList
    |> Seq.map fetchAsync
    |> Async.Parallel 
    |> Async.RunSynchronously
    |> ignore

form.Width  <- 400
form.Height <- 300
form.Visible <- true
form.Text <- "Test download tool"

text.Width <- 200
text.Height <- 50
text.Top <- 0
text.Left <- 0
form.Controls.Add(text)

button.Text <- "click me"
button.Top <- text.Height
button.Left <- 0
button.Click |> Event.add(fun sender -> runAll() |> ignore)
form.Controls.Add(button)

[<STAThread>]
do Application.Run(form)

此致,

Thanks!


您必须将线程上下文切换到 UI 线程Async ThreadPool更新之前text.Text财产。看MSDN链接有关 F# 异步特定的解释。

通过捕获 UI 上下文来修改代码片段后

let uiContext = System.Threading.SynchronizationContext()

紧接着你的let form = new Form()声明和更改fetchAsync定义为

let fetchAsync(name, url:string) =
    async { 
        try 
            let uri = new System.Uri(url)
            let webClient = new WebClient()
            let! html = webClient.AsyncDownloadString(uri)
            do! Async.SwitchToContext(uiContext)
            text.Text <- text.Text + String.Format("Read {0} characters for {1}\n", html.Length, name)
        with
            | ex -> printfn "%s" (ex.Message);
    }

它工作没有任何问题。

UPDATE:在与同事讨论调试器特性后,他强调需要干净地操作 UI 上下文,以下修改现在与运行方式无关:

open System
open System.Net
open Microsoft.FSharp.Control.WebExtensions
open System.Windows.Forms
open System.Threading

let form = new Form()
let text = new Label()
let button = new Button()

let urlList = [ "Microsoft.com", "http://www.microsoft.com/"
                "MSDN", "http://msdn.microsoft.com/"
                "Bing", "http://www.bing.com"
              ]

let fetchAsync(name, url:string, ctx) =
    async {
        try
            let uri = new System.Uri(url)
            let webClient = new WebClient()
            let! html = webClient.AsyncDownloadString(uri)
            do! Async.SwitchToContext ctx
            text.Text <- text.Text + sprintf "Read %d characters for %s\n" html.Length name
        with
            | ex -> printfn "%s" (ex.Message);
    }

let runAll() =
    let ctx = SynchronizationContext.Current
    text.Text <- String.Format("{0}\n", System.DateTime.Now)
    urlList
    |> Seq.map (fun(site, url) -> fetchAsync(site, url, ctx))
    |> Async.Parallel
    |> Async.Ignore
    |> Async.Start

form.Width  <- 400
form.Height <- 300
form.Visible <- true
form.Text <- "Test download tool"

text.Width <- 200
text.Height <- 100
text.Top <- 0
text.Left <- 0
form.Controls.Add(text)

button.Text <- "click me"
button.Top <- text.Height
button.Left <- 0
button.Click |> Event.add(fun sender -> runAll() |> ignore)
form.Controls.Add(button)

[<STAThread>]
do Application.Run(form) 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WinForms 应用程序中的 F# 跨线程 UI 异常 的相关文章

  • 同时激活表单和处理按钮?

    我在 C 中使用 Windows 窗体 我有一个主窗体 其中有几个包含 toolStripButtons 的工具栏 使用包含数据的另一个窗体后 主窗体失去焦点 并且单击 toolStripButton 不会触发 OnClick 事件 第一次
  • Interlocked 类可以安全地与 lock() 混合吗?

    当您将互锁操作与 lock 和其他更高级别的锁 混合使用时 是否可以保证原子读取 我对混合这样的锁定机制时的一般行为以及 Int32 和 Int64 之间的任何差异感兴趣 private Int64 count private object
  • R Shinydashboard 根据选项卡选择显示/隐藏 UI 元素

    如果有人可以提供帮助 我正在努力满足要求 我必须根据用户的选项卡面板选择在仪表板侧栏上显示 隐藏一些元素 这是 UI 代码的一部分 可让您了解我的应用程序的结构 我需要仅在 tabpPanel 2 上显示 Fourthoutput Fift
  • 在仔细锁定但不受信任的代码上使用 Thread.stop()

    我知道Thread stop 已被弃用 并且有充分的理由 它通常不安全 但这并不意味着它是never安全 据我所知 在我想要使用它的上下文中它是安全的 而且 据我所知 我别无选择 上下文是一个两人策略游戏的第三方插件 以国际象棋为例 第三方
  • dotNet:有没有办法在 UI 线程上执行 Join 语句?

    我正在编写一个简单的线程应用程序 当单击开始按钮时 应用程序禁用此按钮 运行 5 个线程 只需进行 For 迭代并更新 5 个进度条 最后一个线程正在等待线程结束 以重新启用我的开始按钮 问题 用户看到按钮在进度条达到 100 之前已启用
  • 如果目标是 x64,为什么 Seq.iter 比 for 循环快 2 倍?

    免责声明 这是微基准测试 如果您对此主题感到不满意 请不要评论诸如 过早优化是邪恶的 之类的言论 示例是针对 x64 Net4 5 Visual Studio 2012 F 3 0 的发行版 并在 Windows 7 x64 中运行 经过分
  • 为 winforms ComboBox 中的单个项目着色?

    我遇到了一个困境 我有一个表单 其中包含许多组合框 其中包含在某些情况下可能无效 过时的信息 选项 项目 我不能简单地从项目中删除过时的信息 但我确实想在选项无效时为用户提供视觉线索 我正在考虑对项目进行着色 可能是红色 来指示它们是否无效
  • 需要多少个线程才能使它们成为错误的选择?

    我必须使用 boost thread 用 C 编写一个不太大的程序 当前的问题是处理大量 可能是数千或数万 数百和数百万也是可能的 数量 可能 的大文件 每个文件彼此独立 并且它们都驻留在同一目录中 我正在考虑使用多线程方法 但问题是 我应
  • 为什么线程本地存储不使用页表映射来实现?

    我希望使用 C 11thread local将非常频繁地访问的每线程布尔标志的关键字 然而 大多数编译器似乎都使用一个表来实现线程本地存储 该表将整数 ID 槽 映射到当前线程上的变量地址 此查找将发生在性能关键的代码路径内 因此我对其性能
  • 当Java中set已经是原子的时候,为什么我们还需要compareAndSet呢?

    因为原子意味着线程安全 当 set 本身在java中是原子和线程安全的时候 我们什么时候使用compareAndSet 举例来说 我想以原子方式设置一个变量 以便每个其他线程都可以看到它 但我希望以线程安全的方式设置该变量 我可以简单地将其
  • 按下 Tab 键时 PictureBox 抛出“参数无效”ArgumentException

    我有一个表单 用户可以首先扫描到位图 扫描完成并加载位图后 我将启用 4 个文本框 每个文本框旁边都有一个名为 从图像剪切 的按钮 当用户单击该按钮时 他们可以在位图中单击并拖动以使用 MODI 获取选定的文本 除了一个恼人的错误之外 这一
  • BlackBerry - 与 FieldManager 一起享受乐趣

    我正在尝试创建一个 View 类 根据它的创建方式提供水平或垂直布局 我正在使用委托来实现此目的 class View extends Manager private Manager mDelegate public View Manage
  • 互斥体没有正确使用?延续过去的问题

    我有第二个问题是该线程的延续 Windows 如何为线程选择内存 https stackoverflow com questions 30487064 how does windows pick memory for threads voi
  • 当 Activity 返回前台时,AlertDialog 不可见

    我写了一个程序支持下载文件 在此下载活动中 我启动一个进度条 然后运行一个线程来执行下载操作 该线程向 UI 线程发送消息以通知已频繁下载了多少个 在主 UI 线程中 我在收到消息时更新进度条显示 如果下载过程中出现任何问题 它会发送另一条
  • 保持 GUI 独立

    我有一个程序 除其他外 有一个命令行界面 可以让用户输入字符串 然后通过网络发送字符串 问题是我不确定如何将 GUI 内部生成的事件连接到网络接口 假设我的 GUI 类层次结构如下所示 GUI gt 主窗口 gt 命令行界面 gt Entr
  • 多线程进程的线程ID可以与另一个正在运行的进程的进程ID相同吗?

    我正在尝试找到一种方法来唯一标识多进程环境中的线程 我有一个服务器 它跟踪连接到它的不同进程 其中一些是多线程的 一些不是 为了识别多线程连接中的线程 我使用线程 ID 作为唯一标识符 在任何给定时间最多有 1 个多线程进程连接 我的问题是
  • 易失性数组 C++

    我有一个应用程序 它有一个指针数组MyObject对象 MyObject arr arr new MyObject 10 应用程序有两个线程 这些线程会创建和删除new MyObject 排列arr 所以arr n 会一直改变 但是MyOb
  • 竞争条件和 Clojure Atoms

    clojure atom 的文档指出 Changes to atoms are always free of race conditions 然而 竞争条件不仅是根据更改定义的 而且是在不同线程中并行逻辑操作的上下文中定义的 我想知道 保证
  • GetChildAtPoint 方法返回错误的控件

    我的表单层次结构是这样的 Form gt TableLayoutOne gt TableLayoutTwo gt Panel gt ListBox 在列表框的 MouseMove 事件中 我有这样的代码 Point cursosPositi
  • 如何在 Tkinter 的 Button 小部件中创建多个标签?

    我想知道如何在 Tkinter 中创建具有多个标签的按钮小部件 如下图所示 带有子标签的按钮 https i stack imgur com jOZRw jpg正如您所看到的 在某些按钮中有一个子标签 例如按钮 X 有另一个小标签 A 我试

随机推荐

  • 如何使用 .querySelector 选择器定位 .style 属性?

    我通过以下方式选择了特定课程 querySelectorAll var hit3 document querySelectorAll lattern hit 3 circle 我现在正在尝试瞄准并调整 style visibility通过执
  • Dart 1.x 书籍仍然适用吗?

    既然 Dart 2 已发布 那么 Dart 1 x 书籍是否仍然相关 Dart 2 文档仅指向迁移指南 我正在尝试学习 Dart 想知道是否应该购买一本基于 Dart 1 x 的书籍 或者应该等待基于 Dart 2 的书籍的出版 Dart
  • 如何跨子图添加层次轴以标记组?

    我有一组可以分组的不同时间序列 例如 下图显示了 A B C 和 D 系列 但是 A 和 B 属于 G1 组 C 和 D 属于 G2 组 我想通过在左侧添加另一个轴来反映这一点 该轴穿过涡轮机组并相应地标记这些轴 到目前为止我已经尝试了一些
  • Eclipse WTP:项目中定义的类的 JSP 文件中出现“导入 ___ 无法解析”错误

    一位 Visual Studio 用户在 Eclipse 中苦苦挣扎 我将一组 servlet JSP 导入到 Oracle Workshop for Weblogic 中的一个项目中 page jsp 有以下导入语句 import com
  • SDN4 - Neo4j OGM + Jackson 2.0

    我尝试在 Spring Data Neo4j 4 0 0RC1 实体上使用 Jackson 2 x 注释 但在我的应用程序上下文启动中看到失败 我有两个 NodeEntities实现一个接口 我已经对接口进行了注释 JsonTypeInfo
  • KMLViewer Apple 的示例不起作用

    我一直在寻找问题的答案 但没有成功 所以就这样 KMLViewer Apple 的示例在某些情况下不起作用 执行自述文件步骤后 我尝试在葡萄牙里斯本和葡萄牙波尔图之间建立一条路线 最奇怪的事情发生了 注释已正确构建 尽管覆盖层 MKPoly
  • MVC Razor 中的 mailto 链接编码

    我有以下型号 public class EmailLinkModel public string mailbody get set public string emailSubject get set public string email
  • 如何在PowerDesigner中隐藏符号编号?

    在 Sybase PowerDesigner 中 当设计采用同一 XXXX 对象 即对象 的 2 个副本 实例的 UML 图时 应用程序会向该符号添加一个数字标识符 如 XXXX 2 可以去掉吗 提前致谢 这似乎不是直接可行的 但是 在 1
  • 与 .pull-right 一起使用时的 .img-responsive 中断

    我有一些图像 pull left and pull right将它们按照特定的模式对齐 我也在用 img responsive 图像如下所示 img src Images test modern jpg class pull right i
  • 使用数据流模型的T触发器

    我正在尝试模拟 t flipflop 的工作 timescale 1ns 1ps module t flipflop input t input clk input clear output q output qbar wire sbar
  • 通过 Jupyter Notebook 中的 shell 激活新的 Conda 环境

    我正在使用用 Python 3 编写的 Jupyter Notebook 并且我想从该 Notebook 中运行 Python 2 脚本 我想知道是否可以从笔记本中运行 Shell 命令 并让这些 Shell 命令在不同的环境下运行 例如
  • IMAGE:您可能需要适当的加载程序来处理此文件类型

    我不知道在 ReactJS webpack 中加载图像的正确加载器是什么 你可以帮我一下吗 我收到此错误 Module parse failed Users imac Desktop fakeeh imgs logo png Unexpec
  • 如何在Python中实现一个好的__hash__函数[重复]

    这个问题在这里已经有答案了 当实现具有多个属性的类时 如下面的玩具示例 处理散列的最佳方法是什么 我猜想 eq and hash 应该是一致的 但是如何实现一个能够处理所有属性的适当的哈希函数呢 class AClass def init
  • Laravel 调度程序 - 在特定时间运行每月的特定日期

    我想在每月的特定日期的特定时间运行任务 现在我使用此代码在该月的 1 号和 15 日运行任务 schedule gt command payments create gt daily gt when function days 1 15 t
  • 使用 Azure Windows 10 运行 Android 模拟器

    我正在尝试在运行 Windows Windows 10 Pro 版本 1809 的 azure VM 上运行 Android 模拟器 但运行 Android 模拟器时收到以下错误消息 C Program Files x86 Android
  • 如何在 Selenium Java 中转换 Katalon 脚本?

    据我们所知 Katalon 现在已经成为付费工具 因此我的 Katalon 脚本需要转换为 Selenium 和 Java 脚本 Katalon 脚本采用 Groovy 语言 使用 Katalon 内置库编写 对象保存在对象存储库中的 rs
  • 在 Pandas 多重索引内重新采样

    我有一些分层数据 这些数据从底部到时间序列数据 看起来像这样 df pandas DataFrame value a values a value b values b index states cities dates df index
  • fill_parent 没有填充 LinearLayout 中的整个屏幕

    我尝试搜索这个答案 最接近的答案是添加 android ressized true 但它已被弃用 如果这个问题已得到解答 我深表歉意 但如果有的话 我找不到它 无论如何 我的应用程序没有填满整个屏幕 我使用的方法在 android 2 2
  • Boost.Spirit.Qi - 规则开头的错误

    如何在规则开始时检测错误 例如 考虑迷你 XML 示例包含在文档中 如果我向解析器提供类似以下内容
  • WinForms 应用程序中的 F# 跨线程 UI 异常

    我在使用 F 开发一个简单的应用程序时遇到问题 该应用程序仅读取所请求的 HTML 页面的长度 当您开发 UI 应用程序时 VB NET C 语言似乎也会出现类似的错误 但我对 F 相当陌生 并不真正想象在 F 中精确解决此类问题的热度 F