c# – 在不阻止UI线程的情况下从任务返回
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 在不阻止UI线程的情况下从任务返回,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3145字,纯文字阅读大概需要5分钟。
内容图文
我有一个返回数据表的方法.我需要在一个线程中运行所有的sql东西,然后能够传回一个数据表,而不会阻塞UI线程.根据我的理解,当您调用Task.Result时,它会阻止UI线程,直到任务完成.我该如何解决这个问题.我读到了关于使用await和async的问题,但我还没有弄清楚如何在任务中使用它.
public static DataTable LaunchLocationMasterListReport(ObservableCollection<string> BuiltConditionsList, ObservableCollection<string> BuiltSortList, ObservableCollection<ListBoxCheckBoxItemModel> ColumnsForReport,
bool LocationNotesCheckBox, ref string reportQuery, ref string reportQueryforSave, ref string reportView, ref string queryCondtions)
{
queryCondtions = BuildConditionAndSorts(queryCondtions, BuiltConditionsList, BuiltSortList);
reportQueryforSave = "SELECT * FROM LocationMasterReportView";
reportView = "LocationMasterReportView";
reportQuery = "SELECT * FROM LocationMasterReportView " + queryCondtions;
return LaunchReport(reportQuery, ColumnsForReport).Result;
}
async private static Task<DataTable> LaunchReport(string reportQuery, ObservableCollection<ListBoxCheckBoxItemModel> ColumnsForReport)
{
SqlConnection myConn = new SqlConnection(Settings.Default.UltrapartnerDBConnectionString);
DataTable dt = new DataTable();
string rq = reportQuery;
Task<DataTable> task = Task.Factory.StartNew(() =>
{
using (SqlCommand comm = new SqlCommand(rq, myConn))
{
myConn.Open();
dt.Load(comm.ExecuteReader());
myConn.Close();
}
if (dt.Rows.Count == 0)
{
MessageBox.Show("Contains No Results");
return null;
}
foreach (ListBoxCheckBoxItemModel lbc in ColumnsForReport)
{
if (!lbc.IsSelected)
{
dt.Columns.Remove(lbc.Name.ToString());
}
}
return dt;
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
return await task;
}
解决方法:
我同意使用async / await是最好的方法.如上所述,当您等待异步方法时,即使声明的返回类型是Task< T>,编译器也会将其转换为T的隐式返回类型.
问题是所有异步方法都必须返回void,Task或Task< T>.因此,一旦你开始使用它们,你必须“冒泡”“异步”方法属性,直到你可以阻止结果或你的方法可能是无效或任务(即你已经消耗了实际)结果).
请参阅这个简单的基于UI的示例:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
statusText.Text = "Running";
statusText.Text = await _ComputeText(true);
statusText.Text = await _ComputeText(false);
}
private static async Task<string> _ComputeText(bool initialTask)
{
string result = await Task.Run(() =>
{
Thread.Sleep(2000);
return initialTask ? "Task is done!" : "Idle";
});
return result;
}
}
请注意,按钮事件处理程序“Button_Click”只是声明为“void”返回.但我可以这样做,因为我在该方法中使用了异步结果.
在您的情况下,在异步任务完成之前,返回的DataTable不可用.因此,您必须将每个方法声明为“异步”,一直回到实际使用DataTable执行某些操作的方法.即使在那里,该方法也需要声明为异步,但您不会返回DataTable,因此该方法可以返回类型为“void”或“Task”.一个常见的场景是这个方法是一个UI事件处理程序,所以“void”应该没问题(并且需要在事件处理程序委托中使用);你的代码还没有调用它.但是在技术上更恰当地使用“任务”,所以如果在你的上下文中有效,你应该这样做.
如果没有一个简洁但完整的例子,很难提供比这更具体的东西.
内容总结
以上是互联网集市为您收集整理的c# – 在不阻止UI线程的情况下从任务返回全部内容,希望文章能够帮你解决c# – 在不阻止UI线程的情况下从任务返回所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。