【发布时间】:2016-04-28 07:58:41
【问题描述】:
在我的 WPF 应用程序中:
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using System.Diagnostics;
namespace CloudKey
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
AuthText.Visibility = Visibility.Hidden;
}
private async void button_Click(object sender, RoutedEventArgs e)
{
AuthText.Visibility = Visibility.Visible;
await Task.Run(() => Authenticate());
Task.Factory.StartNew(() => Authenticate());
Task.Run(() => Authenticate());
Authenticate();
}
void Authenticate()
{
//Do Stuff
}
}
}
无论我尝试用Tasks 以哪种方式调用Authenticate,它都无法运行。我是不是用错了Task?
使用 await(和 async)会引发异常:
System.InvalidOperationException 未处理 消息:在 mscorlib.dll 中发生“System.InvalidOperationException”类型的未处理异常 附加信息:调用线程无法访问此对象,因为不同的线程拥有它。
仅使用 Task.Run 或 Task.Factory.StartNew 会导致 Authenticate 方法根本不运行。如果我向 Authenticate 方法添加断点,则无法到达。
只需使用 Authenticate() 调用该方法即可运行整个方法而不会出现问题,但它会冻结 UI 并生成“AuthText.Visibility = Visibility.Visible;”没用。
说实话,我真的只是希望 UI 更新为消息“正在验证...”,然后在我单击按钮时运行该方法中的所有内容。是否有更简单的方法来做到这一点?
这是供参考的工作代码:
using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using System.Diagnostics;
using System.Threading.Tasks;
namespace CloudKey
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
//private void PasswordBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { button_Click } }
AuthText.Visibility = Visibility.Hidden;
}
private void button_Click(object sender, RoutedEventArgs e) //ON CONTINUE BUTTON CLICK
{
AuthText.Visibility = Visibility.Visible;
Task.Run(() => Authenticate());
}
void Authenticate()
{
Dispatcher.Invoke(
() =>
{
//ALL MY CODE HERE;
});
}
}
}
【问题讨论】:
-
Task.Factory.StartNew(() => Authenticate());应该可以正常工作 - 尽管调用其中的任何 UI 内容都会导致奇怪的事情发生
-
Authenticate是做什么的?可能是在被吞噬的非 UI 线程上抛出异常? -
你怎么知道什么都没发生?定义什么都没有发生?如果你断点,它到达的方法是什么?
-
Task.Run 会像 StartNew 一样启动一个执行该任务的新线程,因为这是一个新线程,您不能保证它在您所依赖的检查之前或之后运行,请尝试添加 await 键工作,这将指示您的代码在继续之前等待任务完成
-
他的代码可能在完成之前就停止了,我也遇到过这种情况,感觉很愚蠢。 @MikeT
标签: c# wpf visual-studio task