如何通过回调方法将进度传递回UI

问题描述 投票:0回答:1

我正在使用Jeff Kluge使用WimgApi软件包的应用程序,将Windows映像应用于磁盘。

我在获取示例回调方法来更新UI组件,特别是表单上的标签(最好是进度条)时遇到问题。

我尝试使用委托来设置值,但这似乎不起作用,因为我无法确定如何将委托传递给回调方法。

如果我使回调方法成为非静态方法,我可以访问表单属性,但是会得到一个死锁,即使禁用死锁破坏,它也会锁定。

我被告知要使用IProgress和异步,但是虽然我可以更改代码以异步运行该方法(这可以正常工作并且UI不会锁定),但我仍然不知道如何获取MyCallbackMethod来发送信息回到用户界面。

//Apply Image Method
public 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);
                }
            }

private static WimMessageResult MyCallbackMethod(WimMessageType messageType, object message, object userData)
        {
            switch (messageType)
            {
                case WimMessageType.Progress:  // Some progress is being sent

                    // Get the message as a WimMessageProgress object
                    //
                    WimMessageProgress progressMessage = (WimMessageProgress)message;

                    // UPDATE UI
                    //THIS IS WHERE I WANT TO SEND BACK PROGRESS INFO

                    break;


                   //REMOVED OTHER MESSAGE CASE STATEMENTS TO CONDENSE CODE


            }

            // Depending on what this method returns, the WIMGAPI will continue or cancel.
            //
            // Return WimMessageResult.Abort to cancel.  In this case we return Success so WIMGAPI keeps going

            return WimMessageResult.Success;
        }

//full example code at Example code is https://github.com/jeffkl/ManagedWimgApi/wiki/Message-Callbacks

如果尝试在回调方法中访问label属性,则会收到非静态字段,方法或属性form1.progressLabel.text的'对象引用。我尝试创建一个委托,但是在回叫中访问该方法似乎有问题。

我看过几个视频,试图理解msdn文档中的委托,回调和诸如async / backgroundworker之类的东西,但我似乎变得更加困惑。

非常感谢任何我应该关注的指针/事物。

c# winforms callback
1个回答
0
投票

在这里做一些假设,但是如果您一次只显示一个进度表,那么应该可以省去对它的静态引用。即:

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.