我知道我错过了一些愚蠢的东西," StartProcess"方法是让UI无法响应,没有任何谷歌搜索和教程让我得到答案。
这是我的代码:
public MainWindow()
{
InitializeComponent();
txtBlock.Text = "Testing";
Initialize();
}
public void Initialize()
{
uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
StartProcess();
}
async void StartProcess()
{
Task<int> result = Task.Factory.StartNew(() =>
{
txtBlock.Text += ("\n starting updater");
while (true)
{
Thread.Sleep(3000);
}
return 0;
}, CancellationToken.None, TaskCreationOptions.LongRunning, uiScheduler);
}
一些背景知识:我正构建一个必须每隔5分钟轮询数据库的应用程序,并使用用户的待办事项列表更新UI,因此是while(true)循环。该应用程序必须在其整个生命周期内连续轮询数据库。
答案 0 :(得分:6)
好吧,你要求TPL调用UI线程中的Func
,它会听从你的话。
在StartNew中,您将uiScheduler
作为TaskScheduler
传递,因此任务将排队到Dispatcher
,这将由UI线程调用。
如果您不想在UI线程中执行,请使用TaskScheduler.Default
,这样做无法更新txtBlock.Text
内的Func
。您需要封送对UI线程的调用,或者只需在txtBlock.Text
之前将Func
设置在StartNew
之外。
如果你在.Net 4.5中,总是更喜欢Task.Run
,请注意StartNew is dangerous。
需要注意的事项:
async
功能。没有
await
关键字方法根本不是异步。你不需要
async关键字(事实上你会收到编译器警告,请付款
注意编译器说的内容。)async Task
,以便您可以在调用者中等待它或附加continuation等等。更新以添加一些代码:
async Task StartProcess()
{
while (true)
{
var result = await Task.Run(()=> MethodWhichCallsDBAndReturnsSomething());
txtBlock.Text = result.ToString();//Use result and update UI
await Task.Delay(5 * 60 * 1000);//await 5 mins
}
}