C# 使用async和Wait不阻塞UI
我的要求是,需要使用async和await呈现与数据绑定的所有框架元素 尝试了以下可能性:C# 使用async和Wait不阻塞UI,c#,wpf,asynchronous,async-await,parallel.foreach,C#,Wpf,Asynchronous,Async Await,Parallel.foreach,我的要求是,需要使用async和await呈现与数据绑定的所有框架元素 尝试了以下可能性: 如果我使用的是asyncmethod().result,它将阻止用户界面和它 将等待很长时间才能完成 如果我使用wait关键字控件来配置foreach(第二个 一)将在完成parallel.foreach()之前命中 因此,您能否建议我渲染元素,在完成并行foreach或而不阻塞UI后,分别调用第二个元素 代码段: 1) Renderingwidget-此方法用于获取与数据绑定的集合中的框架元素 2) F
asyncmethod().result
,它将阻止用户界面和它
将等待很长时间才能完成 public async void RenderingWidget()
{
ConcurrentDictionary<string, EngineChangedEventArgs> controlsToConfigure = new ConcurrentDictionary<string, EngineChangedEventArgs>();
foreach (var engines in MainWindow.ViewModel.RelationalDataManagerList.Values)
{
Dictionary<string, FrameworkElement> controlcollection = CurrentDashboardReport.WidgetCollection;
Parallel.ForEach(controlcollection, async item =>
{
try
{
try
{
controlsToConfigure.TryAdd(item.Key, await FetchDataInParallel(MainWindow.ViewModel.RelationalDashboardReportList[engines.DataSourceName].Reports, item.Key,));
}
catch (Exception ex)
{
ExceptionLog.WriteExceptionLog(ex, null);
throw new ParallelException(ex, item.Key);
}
}
catch (ParallelException ex)
{
exceptions.Enqueue(ex);
ExceptionLog.WriteExceptionLog(ex, GeneratedQueryText);
}
});
if (exceptions.Count > 0)
{
foreach (var nonRenderedControls in exceptions)
{
controlsToConfigure.TryAdd(nonRenderedControls.ReportName, await FetchDataInParallel(CurrentDashboardReport.Reports, nonRenderedControls.ReportName));
}
}
}
foreach (var control in controlsToConfigure)
{
(CurrentDashboardReport.WidgetCollection[control.Key] as DashboardDataControl).CurrentDashboardReport.OnActiveColumnsChanged(control.Value);
}
}
public async Task<EngineChangedEventArgs> FetchDataInParallel(RelationalReportCollection reports, string myReport)
{
var dataTable = await GetTableFromServer(reports.Query);
eventArgs = new EngineChangedEventArgs
{
ItemsSource = dataTable
};
return eventArgs;
}
public async Task<DataTable> GetTableFromServer(string query)
{
var resultTable = new DataTable
{
Locale = CultureInfo.InvariantCulture
};
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(query, sqlConnection)
SqlDataReader dataReader = null;
try
{
if (sqlConnection.State != ConnectionState.Open)
{
sqlConnection.Open();
}
dataReader =await command.ExecuteReaderAsync();
resultTable.Load(dataReader);
return resultTable;
}
finally
{
if (dataReader != null)
{
dataReader.Dispose();
}
command.Dispose();
return resultTable;
}
}
公共异步void RenderingWidget()
{
ConcurrentDictionary controlsToConfigure=新建ConcurrentDictionary();
foreach(MainWindow.ViewModel.RelationalDataManagerList.Values中的var引擎)
{
Dictionary controlcollection=CurrentDashboardReport.WidgetCollection;
Parallel.ForEach(controlcollection,异步项=>
{
尝试
{
尝试
{
controlsToConfigure.TryAdd(item.Key,Wait FetchDataInParallel(MainWindow.ViewModel.RelationalDashboardReportList[engines.DataSourceName]。报告,item.Key,);
}
捕获(例外情况除外)
{
ExceptionLog.WriteExceptionLog(ex,null);
抛出新的ParallelException(例如,item.Key);
}
}
捕获(并行异常)
{
例外情况。排队(ex);
ExceptionLog.WriteExceptionLog(例如,GeneratedQueryText);
}
});
如果(异常数>0)
{
foreach(异常情况下的var nonRenderedControls)
{
controlsToConfigure.TryAdd(nonRenderedControls.ReportName,wait FetchDataInParallel(CurrentDashboardReport.Reports,nonRenderedControls.ReportName));
}
}
}
foreach(controlsToConfigure中的var控制)
{
(CurrentDashboardReport.WidgetCollection[control.Key]作为DashboardDataControl)。CurrentDashboardReport.OnActiveColumnsChanged(control.Value);
}
}
公共异步任务FetchDataInParallel(RelationalReportCollection报告,字符串myReport)
{
var dataTable=await GetTableFromServer(reports.Query);
eventArgs=新的EngineChangedEventArgs
{
ItemsSource=dataTable
};
返回事件参数;
}
公共异步任务GetTableFromServer(字符串查询)
{
var resultTable=新数据表
{
Locale=CultureInfo.InvariantCulture
};
SqlConnection SqlConnection=新的SqlConnection(connectionString);
SqlCommand=newsqlcommand(查询,sqlConnection)
SqlDataReader=null;
尝试
{
if(sqlConnection.State!=ConnectionState.Open)
{
sqlConnection.Open();
}
dataReader=等待命令。ExecuteReaderAsync();
resultable.Load(数据读取器);
返回结果;
}
最后
{
if(dataReader!=null)
{
dataReader.Dispose();
}
command.Dispose();
返回结果;
}
}
并行。ForEach
在异步
/调用期间释放线程时,不能很好地处理异步
/等待
。有关这方面的更多信息,请参阅以下问题:
您可以在线程池线程上调用Parallel.ForEach
,然后使用Task.whalll
方法等待所有任务完成后再继续:
public async void RenderingWidget()
{
ConcurrentDictionary<string, EngineChangedEventArgs> controlsToConfigure = new ConcurrentDictionary<string, EngineChangedEventArgs>();
List<Task> tasks = new List<Task>();
foreach (var engines in MainWindow.ViewModel.RelationalDataManagerList.Values)
{
Dictionary<string, FrameworkElement> controlcollection = CurrentDashboardReport.WidgetCollection;
tasks.Add(Task.Run(() =>
{
Parallel.ForEach(controlcollection, item =>
{
try
{
try
{
controlsToConfigure.TryAdd(item.Key, FetchDataInParallel(MainWindow.ViewModel.RelationalDashboardReportList[engines.DataSourceName].Reports, item.Key).Result);
}
catch (Exception ex)
{
ExceptionLog.WriteExceptionLog(ex, null);
throw new ParallelException(ex, item.Key);
}
}
catch (ParallelException ex)
{
exceptions.Enqueue(ex);
ExceptionLog.WriteExceptionLog(ex, GeneratedQueryText);
}
});
if (exceptions.Count > 0)
{
foreach (var nonRenderedControls in exceptions)
{
controlsToConfigure.TryAdd(nonRenderedControls.ReportName, FetchDataInParallel(CurrentDashboardReport.Reports, nonRenderedControls.ReportName).Result);
}
}
}));
}
await Task.WhenAll(tasks);
foreach (var control in controlsToConfigure)
{
(CurrentDashboardReport.WidgetCollection[control.Key] as DashboardDataControl).CurrentDashboardReport.OnActiveColumnsChanged(control.Value);
}
}
public async Task<EngineChangedEventArgs> FetchDataInParallel(RelationalReportCollection reports, string myReport)
{
var dataTable = await GetTableFromServer(reports.Query).ConfigureAwait(false);
return new EngineChangedEventArgs
{
ItemsSource = dataTable
};
}
公共异步void RenderingWidget()
{
ConcurrentDictionary controlsToConfigure=新建ConcurrentDictionary();
列表任务=新列表();
foreach(MainWindow.ViewModel.RelationalDataManagerList.Values中的var引擎)
{
Dictionary controlcollection=CurrentDashboardReport.WidgetCollection;
tasks.Add(Task.Run)(()=>
{
Parallel.ForEach(controlcollection,item=>
{
尝试
{
尝试
{
controlsToConfigure.TryAdd(item.Key,FetchDataInParallel(MainWindow.ViewModel.RelationalDashboardReportList[engines.DataSourceName]。报告,item.Key)。结果);
}
捕获(例外情况除外)
{
ExceptionLog.WriteExceptionLog(ex,null);
抛出新的ParallelException(例如,item.Key);
}
}
捕获(并行异常)
{
例外情况。排队(ex);
ExceptionLog.WriteExceptionLog(例如,GeneratedQueryText);
}
});
如果(异常数>0)
{
foreach(异常情况下的var nonRenderedControls)
{
controlsToConfigure.TryAdd(nonRenderedControls.ReportName,FetchDataInParallel(CurrentDashboardReport.Reports,nonRenderedControls.ReportName).Result);
}
}
}));
}
等待任务。何时(任务);
foreach(controlsToConfigure中的var控制)
{