为了账号安全,请及时绑定邮箱和手机立即绑定

如何从回调方法将进度传回 UI

如何从回调方法将进度传回 UI

PHP
慕的地8271018 2024-01-20 21:29:30
我正在开发一个应用程序,该应用程序使用 Jeff Kluge 的 WimgApi 包将 Windows 映像应用到磁盘。我在获取示例回调方法来更新 UI 组件时遇到问题,特别是表单上的标签(最好是进度条)。我尝试使用委托来设置值,但这似乎不起作用,因为我无法弄清楚如何将委托传递给回调方法。如果我将回调方法设置为非静态,我可以访问表单属性,但随后我会遇到死锁,即使我禁用死锁打破,它也会锁定。我被告知要考虑使用 IProgress 和 async,但是虽然我可以更改代码以异步运行该方法(这有效并且 UI 不会锁定),但我仍然无法弄清楚如何让 MyCallbackMethod 将信息发送回用户界面。//Apply Image Methodpublic void ApplyImage()        {            using (WimHandle wimHandle = WimgApi.CreateFile(@"C:\osimages\test.wim",                WimFileAccess.Read,                WimCreationDisposition.OpenExisting,                WimCreateFileOptions.None,                WimCompressionType.None))            {                // Always set a temporary path                WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));                // Register a method to be called while actions are performed by WIMGAPi for this .wim file                WimgApi.RegisterMessageCallback(wimHandle, MyCallbackMethod);                try                {                    // Get a handle to the first image in the .wim file                    using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, 1))                    {                        // Apply the image contents to C:\Apply                        // This call is blocking but WIMGAPI will be calling MyCallbackMethod() during the process                        WimgApi.ApplyImage(imageHandle, @"X:\", WimApplyImageOptions.None);                    }                }                finally                {                    // Be sure to unregister the callback method                    //                    WimgApi.UnregisterMessageCallback(wimHandle, MyCallbackMethod);                }            }如果我尝试在回调方法中访问标签属性,我会收到“非静态字段、方法或属性 form1.progressLabel.text 需要对象引用”。我尝试创建委托,但似乎在访问回调中的方法时遇到问题。我观看了几个视频并尝试了解有关委托、回调和 async/backgroundworker 等内容的 msdn 文档,但我似乎更加困惑。非常感谢我应该关注的任何指示/事情。
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超12个赞

免责声明:我对 WimgApi 软件包没有任何经验。但是该方法存在重载,WimgApi.RegisterMessageCallback该方法采用将传递给回调的任意对象。所以请尝试这个:


WimgApi.RegisterMessageCallback(wimHandle, MyCallbackMethod, this);

并在回调中:


var form = (MyForm)userData;

if (form.InvokeRequired)

{

    form.Invoke((MethodInvoker)(() => UpdateProgressUI(...)));

}

else

{

    form.UpdateProgressUI(...);

}


查看完整回答
反对 回复 2024-01-20
?
森栏

TA贡献1810条经验 获得超5个赞

在这里做出一些假设,但如果您一次只显示一个进度表单,那么您应该能够避免存储对其的静态引用。IE:


class ProgressForm

{

    private static ProgressForm staticRef;


    private void Form_Loaded(object sender, EventArgs e)

    {

        staticRef = this;

    }


    private void InternalCallback(uint m, IntPtr w, IntPtr l, IntPtr u)

    {

        // Ensure we're touching UI on the right thread

        if (Dispatcher.InvokeRequired)

        {

            Dispatcher.Invoke(() => InternalCallback(m, w, l, u));

            return;

        }


        // Update UI components

        // ....

    }


    private static uint StaticCallback(uint m, IntPtr w, IntPtr l, IntPtr u)

    {

        staticRef?.InternalCallback(m, w, l, u);


        return 0;

    }

}


查看完整回答
反对 回复 2024-01-20
  • 2 回答
  • 0 关注
  • 41 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信