C# Windows 8.1通用应用程序中BackgroundWorker的替代方案是什么?
我正在将我的Windows Phone应用迁移到Windows通用应用。在手机应用程序中,我使用BackgroundWorker检索数据库,然后在UI中显示。下面是我在WindowsPhone8中准备的课程以及它的名称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
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是两个函数
问题:
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
}
}
}