Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows 8.1通用应用程序中BackgroundWorker的替代方案是什么?_C#_Win Universal App - Fatal编程技术网

C# Windows 8.1通用应用程序中BackgroundWorker的替代方案是什么?

C# Windows 8.1通用应用程序中BackgroundWorker的替代方案是什么?,c#,win-universal-app,C#,Win Universal App,我正在将我的Windows Phone应用迁移到Windows通用应用。在手机应用程序中,我使用BackgroundWorker检索数据库,然后在UI中显示。下面是我在WindowsPhone8中准备的课程以及它的名称 public class TestBackgroundWorker { private BackgroundWorker backgroundWorker; ProgressIndicator progressIndicator; public dele

我正在将我的Windows Phone应用迁移到Windows通用应用。在手机应用程序中,我使用BackgroundWorker检索数据库,然后在UI中显示。下面是我在WindowsPhone8中准备的课程以及它的名称

public class TestBackgroundWorker
{
    private BackgroundWorker backgroundWorker;
    ProgressIndicator progressIndicator;

    public delegate void functionToRunInBackground();
    public functionToRunInBackground currentFunctionToExecute;

    public delegate void callbackFunction();
    public callbackFunction functionToSendResult;

    private bool isCancellationSupported;


    private string message;


    /// <summary>
    /// 
    /// </summary>
    /// <param name="functionNameToExecute">specifies function name to be executed in background</param>
    /// <param name="isCancellable">Flag which specifies whether the operation is cancellable or not</param>
    /// <param name="functionNameWhichGetsResult">Specifies call back function to be executed after the completion of operation</param>
    public MCSBackgroundWorker(functionToRunInBackground functionNameToExecute, bool isCancellable, string messageToDisplay, callbackFunction functionNameWhichGetsResult)
    {
        currentFunctionToExecute = functionNameToExecute;
        functionToSendResult = functionNameWhichGetsResult;
        isCancellationSupported = isCancellable;
        message = messageToDisplay;
        backgroundWorker = new BackgroundWorker();
        backgroundWorker.WorkerSupportsCancellation = isCancellable;
        backgroundWorker.DoWork += backgroundWorker_DoWork;
        backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
    }

    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        deactivateProgressIndicator();
        functionToSendResult();
    }

    void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        if (currentFunctionToExecute != null)
        {
            currentFunctionToExecute();
        }
    }


    public void cancelBackgroundOperation()
    {
        if (isCancellationSupported == true)
        {
            backgroundWorker.CancelAsync();
        }
    }


    public void Start()
    {
        backgroundWorker.RunWorkerAsync();
        activateProgressIndicator();
    }


    void activateProgressIndicator()
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            var currentPage = App.RootFrame.Content as PhoneApplicationPage;
            SystemTray.SetIsVisible(currentPage, true);
            SystemTray.SetOpacity(currentPage, 0.5);
            SystemTray.SetBackgroundColor(currentPage, Colors.White);
            SystemTray.SetForegroundColor(currentPage, Colors.Black);

            progressIndicator = new ProgressIndicator();
            progressIndicator.IsVisible = true;
            progressIndicator.IsIndeterminate = true;
            progressIndicator.Text = message;

            SystemTray.SetProgressIndicator(currentPage, progressIndicator);

        });

    }

    void deactivateProgressIndicator()
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            if (progressIndicator != null)
            {
                var currentPage = App.RootFrame.Content as PhoneApplicationPage;
                progressIndicator.IsVisible = false;
                SystemTray.SetIsVisible(currentPage, false);

            }

        });
    }


    public bool isBackgroundWorkerBusy()
    {
        return backgroundWorker != null ? backgroundWorker.IsBusy : false;
    }

}
这里,loadReprtsFromDB和showReports是两个函数

问题:

  • 有人能建议如何在Windows8.1中实现同样的功能吗

  • PhoneApplicationService.Current.State是否有其他选择


  • 我想,即使对于桌面,
    任务
    进度
    类也为
    BackgroundWorker
    提供了一个很好的替代方案,它们都在Windows Phone 8.1上受支持。
    任务
    类提供了启动然后干净地等待后台操作的机制,而
    进度
    类提供了报告进度的机制(不是您的示例或问题的一部分,但我提到它是因为这是
    任务
    以及
    异步
    /
    等待
    不提供自
    BackgroundWorker

    您的示例可以更改为以下内容:

    public class TestBackgroundWorker
    {
        private Task _task;
        private CancellationTokenSource _cancelSource;
    
        public CancellationToken CancellationToken
        {
            get { return _cancelSource != null ? _cancelSource.Token : null; }
        }
    
        ProgressIndicator progressIndicator;
    
        public readonly Action<TestBackgroundWorker> currentFunctionToExecute;
    
        private string message;
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="functionNameToExecute">specifies function name to be executed in background</param>
        /// <param name="isCancellable">Flag which specifies whether the operation is cancellable or not</param>
        /// <param name="functionNameWhichGetsResult">Specifies call back function to be executed after the completion of operation</param>
        public MCSBackgroundWorker(Action<TestBackgroundWorker> functionNameToExecute, bool isCancellable, string messageToDisplay)
        {
            currentFunctionToExecute = functionNameToExecute;
            _cancelSource = isCancellable ? new CancellationTokenSource() : null;
            message = messageToDisplay;
        }
    
        public void cancelBackgroundOperation()
        {
            if (_cancelSource != null)
            {
                _cancelSource.Cancel();
            }
        }
    
        public async Task Start()
        {
            activateProgressIndicator();
            _task = Task.Run(() => currentFunctionToExecute(this));
            await _task;
            _task = null;
            deactivateProgressIndicator();
        }
    
        void activateProgressIndicator()
        {
            // In theory, you should not need to use Dispatcher here with async/await.
            // But without a complete code example, it's impossible for me to
            // say for sure, so I've left it as-is.
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                var currentPage = App.RootFrame.Content as PhoneApplicationPage;
                SystemTray.SetIsVisible(currentPage, true);
                SystemTray.SetOpacity(currentPage, 0.5);
                SystemTray.SetBackgroundColor(currentPage, Colors.White);
                SystemTray.SetForegroundColor(currentPage, Colors.Black);
    
                progressIndicator = new ProgressIndicator();
                progressIndicator.IsVisible = true;
                progressIndicator.IsIndeterminate = true;
                progressIndicator.Text = message;
    
                SystemTray.SetProgressIndicator(currentPage, progressIndicator);
            });
        }
    
        void deactivateProgressIndicator()
        {
            // Likewise.
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                if (progressIndicator != null)
                {
                    var currentPage = App.RootFrame.Content as PhoneApplicationPage;
                    progressIndicator.IsVisible = false;
                    SystemTray.SetIsVisible(currentPage, false);
                }
            });
        }
    
        public bool isBackgroundWorkerBusy()
        {
            return _task != null;
        }
    }
    
    private async Task loadReports()
    {
        bgWorker = new TestBackgroundWorker(loadReportsFromDB, true, "Loading...");
        await bgWorker.Start();
        showReports();
    }
    
    void loadReportsFromDB(TaskBackgroundWorker worker)
    {
        while (...)
        {
            if (worker.CancellationToken.IsCancellationRequested)
            {
                return; // or whatever
            }
        }
    }
    
    要处理取消,需要将
    functionNameToExecute
    委托用于接受
    TaskBackgroundWorker
    实例作为参数的方法,以便它可以检索
    CancellationToken
    属性值以检查取消(类似于
    DoWork()
    event handler…尽管您的代码示例实际上没有建议任何机制,实际的后台操作代码甚至可以通过这些机制检测取消)

    请注意,使用
    async
    /
    await
    ,如果您愿意,您的任务也可以通过
    task
    类型而不是
    task
    返回一个值。上面的示例可以很容易地修改以适应这一点,
    async
    /
    await
    的功能是我喜欢它而不是
    背景的最大原因之一dWorker
    (没有干净的、编译器支持的机制从后台操作返回结果)


    警告:由于缺乏完整的代码示例,我没有必要尝试实际编译和测试任何代码。因此,以上内容严格是“由浏览器编写的”。为了便于说明,这应该足够了,但我为可能存在的任何打字错误提前道歉。

    谢谢@Peter。我会试试这个。但是为什么要删除callBackFunction参数?你能回答我的第二个问题吗?我删除了该参数,因为
    异步
    /
    等待
    模式不需要它。正如我所说的但是在调用代码的示例中,您可以在调用
    async
    方法之后直接调用该方法,而不是传递要调用的委托
    private async Task loadReports()
    {
        bgWorker = new TestBackgroundWorker(loadReportsFromDB, true, "Loading...");
        await bgWorker.Start();
        showReports();
    }
    
    void loadReportsFromDB(TaskBackgroundWorker worker)
    {
        while (...)
        {
            if (worker.CancellationToken.IsCancellationRequested)
            {
                return; // or whatever
            }
        }
    }