L'obtention d'un de Ne pas attendre, vide, sur une méthode que j'ai envie d'attendre sur
Je suis sur une équipe de l'écriture d'une application WPF. Nous devons faire en sorte que lorsqu'un utilisateur masque/affiche les différentes colonnes qu'il en reflète que dans un contrôle ReportViewer sur l'une des vues. Dans les tests, nous avons constaté que cela prend beaucoup de temps pour ajouter les données à la ReportViewer de sources de données; parfois de l'ordre de quelques secondes à une minute. Trop long je pense que pour les utilisateurs. Donc, je suis en train d'utiliser C#'async et await. Cependant, lorsque j'ai appliqué attendent à la ligne qui est le processus de porc, puis le compiler, j'obtiens une erreur du compilateur C#, "de Ne pas attendre, de "vide"". Dans ce cas, je ne peux pas changer ce que l' .NET framework revient, son vide. Alors, comment puis-je gérer cette situation? Voici le code:
private async Task GenerateReportAsync()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.Clear();
int iCols = 0;
//Get the column names
if (Columns.Count == 0) //Make sure it isn't populated twice
{
foreach (DataGridColumn col in dataGrid.Columns)
{
if (col.Visibility == Visibility.Visible)
{
Columns.Add(col.Header.ToString()); //Get the column heading
iCols++;
}
}
}
//Create a DataTable from the rows
var itemsSource = dataGrid.ItemsSource as IEnumerable<Grievance>;
if (this.rptViewer != null)
{
rptViewer.Reset();
}
rptViewer.LocalReport.DataSources.Clear();
if (m_rdl != null)
{
m_rdl.Dispose();
}
Columns = GetFieldOrder();
m_rdl = CoreUtils.GenerateRdl(Columns, Columns);
rptViewer.LocalReport.LoadReportDefinition(m_rdl);
//the next line is what takes a long time
await rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", CoreUtils.ToDataTable(itemsSource)));
rptViewer.RefreshReport();
}
await
si vous pensez que l'attente de quelque chose qui prend du temps est une solution à votre problème. Pouvez-vous décrire quelles sont vos croyances à propos de await
? Il n'a de sens que pour attendre quelque chose qui est déjà asynchrone; croyez-vous qui attendent les rend quelque chose qui n'est pas asynchrone dans une opération asynchrone? Il ne le fait pas.C'est ma compréhension que l'utilisation de async/await permet de revenir au thread de l'INTERFACE utilisateur, plutôt que de le suspendre, dans l'attente pour certains processus de travail à terminer. Mais je vous remercie de me le demander.
Mon point est que si la fonction est nulle retour et déjà asynchrone puis il ne devrait pas prendre beaucoup de temps. Si elle est vide de retour, synchrone, et la latence élevée alors il n'y a rien à
await
. Attendent pour la gestion de l'existant opération asynchrone. Si vous avez un temps de latence élevé de l'opération que vous souhaitez être asynchrone, await
ne va pas vous aider. Vous allez avoir à comprendre comment faire il asynchrone via un autre mécanisme.
OriginalL'auteur Rod | 2017-02-14
Vous devez vous connecter pour publier un commentaire.
Pour les méthodes qui sont intrinsèquement synchrone, vous avez besoin de les envelopper dans votre propre
Task
de sorte que vous pouvez attendre. Dans votre cas, je voudrais juste utiliserTask.Run
:Il y a d'autres façons de générer une tâche, mais celui-ci est probablement le plus facile. Si cela met à jour un composant de l'INTERFACE utilisateur, il sera susceptible de lever une exception, car ces opérations doivent se faire sur le thread d'INTERFACE utilisateur. Dans ce cas, essayez d'obtenir de l'INTERFACE utilisateur liées pièce à l'écart de la partie et seulement enrouler la partie longue de la
Task
.Absolument, j'ai pris note de ce.
J'ai pris votre suggestion et est venu avec les éléments suivants: DataTable dtTmp = null; attendent Tâche.Exécuter(() => dtTmp = CoreUtils.ToDataTable(itemsSource)); rptViewer.LocalReport.Les sources de données.Add(new ReportDataSource("MyData", dtTmp)); je ne savais pas que l'utilisation de l'attendent sur un composant de l'INTERFACE utilisateur serait la cause d'une exception. Merci pour le tête de! Le ci-dessus donne le contrôle de retour pour le thread d'INTERFACE utilisateur rapidement. Merci, encore une fois..
ce n'est pas la attendent que provoque l'exception c'est le Tas.Run qui ne.
OriginalL'auteur BradleyDotNET
Je peux être quasiment certain que l'ensemble de la ligne n'est pas la lenteur de la ligne, il est beaucoup plus probable que
CoreUtils.ToDataTable(itemsSource)
est la lenteur de la pièce et qui est la partie qui doit être amélioré.Vous n'avez pas de comprendre la source de
ToDataTable
donc je ne peux pas dire à coup sûr que le meilleur moyen serait, la première et la meilleure option serait d'écrire une nouvelle version de la fonction qui met à profit les appels asynchrones en interne pour créer une fonction qui permet à l'attendent.La seconde, moins performant option est de faire de la lenteur de la partie sur un thread d'arrière-plan à l'aide de
Task.Run
puis retour sur le thread de l'INTERFACE utilisateur de définir la source de données que nécessaire.OriginalL'auteur Scott Chamberlain