【发布时间】:2022-01-12 13:45:00
【问题描述】:
我正忙于在 Windows 窗体中开发一个股票跟踪器应用程序以备不时之需。为了优化我的代码,我决定重写使所有内容保持最新的 main 函数。我认为选择正确的行并从那里工作会更容易,而不是为正确的控件搜索所有控件。问题是:它不断跳过我要运行的任务,并且不再更新它。我已经尝试了很多我在互联网上找到的东西,但我无法让它工作。所以我恢复到最简单的原始代码形式,看看你们是否有想法。以下是这一切的精髓:
public async void KeepUpdatingEverything(List<object> positionInfo, List<string> tickerList)
{
foreach (string ticker in tickerList)
{
//code that gets the right row
List<object> priceInfo = await GetStockPrices(ticker));
//code that updates all the labels
}
}
这个想法是,当调用 KeepUpdating 函数时,它会检查带有代码的列表,获取每个代码的价格并随后更新所有相关标签。但我似乎无法让它工作,因为它一直跳过异步调用。有什么想法吗?
在输入第一个代码时,会调用一次 KeepUpdatingEverything,之后它只会不断更新代码列表。
private async void button1_Click(object sender, EventArgs e)
{
string ticker;
using (Prompt prompt = new Prompt("Enter the ticker symbol", "Add ticker"))
{
ticker = prompt.Result;
ticker = ticker.ToUpper();
if (!string.IsNullOrEmpty(ticker))
{
using (Prompt prompt2 = new Prompt("Enter your volume", "Add ticker"))
{
if (Int32.TryParse(prompt2.Result, out int volume) == true)
{
using (Prompt prompt3 = new Prompt("Enter your buy price", "Add ticker"))
{
if (Double.TryParse(prompt3.Result, out double buyPrice) == true)
{
try
{
List<object> priceInfo = await GetStockPrices(ticker);
FillTickerLabel(ticker);
List<object> positionInfo = GetPositionVars(ticker, volume, buyPrice, Convert.ToDouble(priceInfo[1]));
FillPositionLabel(ticker, priceInfo[0].ToString(), positionInfo);
List<object> changeInfo = GetChangeVars(ticker, priceInfo);
FillChangeLabels(ticker, priceInfo[0].ToString(), changeInfo);
List<string> tickerList = new List<string>();
tickerList.Add(ticker);
if (tickerList.Count <= 1)
{
_cancellationToken = new CancellationTokenSource();
_runningTask = StartTimer(() => KeepUpdatingEverything(positionInfo, tickerList), _cancellationToken);
}
}
catch
{
MessageBox.Show("Ticker does not exist, or entered incorrect value somewhere else");
}
}
else
{
MessageBox.Show("You did not enter one of the textboxes correctly");
}
}
}
else
{
MessageBox.Show("You did not enter one of the textboxes correctly");
}
}
}
else
{
MessageBox.Show("You did not enter one of the textboxes correctly");
}
}
}
最后是StartTimer函数:
private async Task StartTimer(Action action, CancellationTokenSource cancellationTokenSource)
{
try
{
while (!cancellationTokenSource.IsCancellationRequested)
{
await Task.Delay(5000, cancellationTokenSource.Token);
action();
}
}
catch (OperationCanceledException) { }
}
【问题讨论】:
-
KeepUpdatingEverything方法在哪里/如何被调用?你也知道这篇文章吗? Avoid async void. -
_runningTask = StartTimer(() => KeepUpdatingEverything...StartTimer 方法在做什么? -
@TheodorZoulias 启动计时器以每 5 秒运行一次 KeepUpdatingEverything。我检查了这篇文章,但将其更改为 Task 类型并没有任何区别。我将在主帖中编辑完整的 StartTimer 代码
-
“它一直跳过我要运行的任务,并且不再更新它。”
-
你知道
await GetStockPrices(ticker)是否抛出异常?在这种情况下,我的期望是异常会升级为应用程序崩溃。除非存在一些额外的错误吞噬代码(空catch块),否则您已从问题中省略。
标签: c# winforms asynchronous foreach stock