我试图编写一款能够不断提高加密货币价格的应用程序。 CallAPI()函数从JSON格式的在线API获取价格,解析它,然后将其发送到应用程序前端的文本块。它在while循环中运行,并且之间有一个短暂的中断:
public MainPage()
{
this.InitializeComponent();
KrakenConnector KC = new KrakenConnector();
while (true)
{
CallAPI(KC, 0);
CallAPI(KC, 1);
CallAPI(KC, 2);
CallAPI(KC, 3);
CallAPI(KC, 4);
CallAPI(KC, 5);
Task.Delay(1000).Wait();
}
}
我刚刚获得了Windows通用应用的默认启动画面,而且它没有进入实际应用。我怎样才能解决这个问题?为什么不进入应用程序?我不应该在CallAPI函数中设置文本块吗?
答案 0 :(得分:0)
试试这个
private bool isLoaded = true;
public MainPage()
{
this.InitializeComponent();
this.WorkItAsync();
this.Unloaded += (s, e) => this.isLoaded = false;
}
private async Task WorkItAsync()
{
var KC = new KrakenConnector();
while (this.isLoaded)
{
CallAPI(KC, 0);
CallAPI(KC, 1);
CallAPI(KC, 2);
CallAPI(KC, 3);
CallAPI(KC, 4);
CallAPI(KC, 5);
await Task.Delay(1000);
}
}
答案 1 :(得分:0)
您的MainPage
构造函数永远不会退出。此外,您在UI线程上进行了和调用Task.Delay
,这是禁忌。你应该在后台线程上做。
这是一个更好的方法的骨架:
public sealed partial class MainPage
{
private bool running;
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
running = true;
// Start background thread
Task.Run(
async () =>
{
int counter = 0;
while (running)
{
// UI updates must happen on the UI thread;
// we use the Dispatcher for this:
await Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() => test.Text = counter.ToString());
await Task.Delay(1000);
++counter;
}
});
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
running = false;
}
相应的XAML:
<Page
x:Class="App2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBlock
x:Name="test"
FontSize="24"
HorizontalAlignment="Center"
Margin="0,24,0,0" />
<!-- The button doesn't do anything; it's just to show that the UI is live -->
<Button
Content="Hello, world!"
HorizontalAlignment="Center"
Margin="0,24,0,0" />
</StackPanel>
</Page>
使用bool
来控制循环有点简单;更好的方法是使用CancellationTokenSource
,它还能够阻止Task.Delay
在其轨道上死亡。这是另一个需要:
public sealed partial class MainPage
{
private CancellationTokenSource cancellationTokenSource;
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
cancellationTokenSource = new CancellationTokenSource();
CancellationToken token = cancellationTokenSource.Token;
// Start background thread
Task.Run(
async () =>
{
int counter = 0;
while (true)
{
if (token.IsCancellationRequested)
{
// Stop the loop; we're moving away from the page
break;
}
// UI updates must happen on the UI thread;
// we use the Dispatcher for this:
await Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() => test.Text = counter.ToString());
await Task.Delay(1000, token);
++counter;
}
});
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
cancellationTokenSource?.Cancel();
}
}