C# 如何在WPF中加速异步函数

C# 如何在WPF中加速异步函数,c#,wpf,asynchronous,C#,Wpf,Asynchronous,我在一个库中创建了这个函数。我将此功能用于控制台和WPF应用程序。在我的控制台应用程序中,此功能在不到一秒钟的时间内完成,大收藏最多80项,小收藏如5项 此外,在我的WPF应用程序中,当我使用最多80个项的集合运行此函数时,完成执行需要一分钟,但最多5个项的项在不到一秒钟的时间内完成执行 C#代码: 公共异步任务GetTemplates(字符串showName) { 字典d=新字典(); //获取show“DemoShow”的元素集合uri var elementCollectionUriTas

我在一个库中创建了这个函数。我将此功能用于控制台和WPF应用程序。在我的控制台应用程序中,此功能在不到一秒钟的时间内完成,大收藏最多80项,小收藏如5项

此外,在我的WPF应用程序中,当我使用最多80个项的集合运行此函数时,完成执行需要一分钟,但最多5个项的项在不到一秒钟的时间内完成执行

C#代码:

公共异步任务GetTemplates(字符串showName)
{
字典d=新字典();
//获取show“DemoShow”的元素集合uri
var elementCollectionUriTask=Task.Run(()=>GetElementCollectionUri(vizServiceDocURL,showName));
var elementCollectionUri=等待elementCollectionUriTask;
var templateCollectionUriTask=Task.Run(()=>GetTemplateCollectionUri(elementCollectionUri));
var templateCollectionUri=等待templateCollectionUriTask;
var templateNamesTask=Task.Run(()=>GetListOfTemplateName(templateCollectionUri));
var templateNames=等待templateNamesTask;
//从每个节目中获取名称和链接,并将其添加到词典中
foreach(templateNames中的字符串templateName)
{
var templateCollectionEntryUriTask=Task.Run(()=>GetTemplateCollectionEntryUri(templateCollectionUri,templateName));
var templateCollectionEntryUri=等待templateCollectionEntryUriTask;
var elementModelUriTask=Task.Run(()=>GetTemplateElementModelUri(templateCollectionUri,templateName));
var elementModelUri=wait elementModelUriTask;
等待任务。运行(()=>PrintVdfModel(elementModelUri));
string[]links=新字符串[2]{templateCollectionEntryUri,elementModelUri};
d、 添加(模板名称、链接);
}
返回d;
}

正如我在评论中提到的,如果您想加快这些作业的处理速度,那么您当然可以在循环上做一些工作,将逻辑并行应用于所有模板名称

public async Task<Dictionary<string, string[]>> GetTemplates(string showName)
{
    Dictionary<string, string[]> d = new Dictionary<string, string[]>();

    // Get element collection uri of show "DemoShow"
    var elementCollectionUri = GetElementCollectionUri(vizServiceDocURL, showName);

    var templateCollectionUri = GetTemplateCollectionUri(elementCollectionUri);

    var templateNames = GetListOfTemplateName(templateCollectionUri);

    //get the name and links from each show and add them to the dictionary
    // Keep a temporary List of Tasks
    List<Task> allTasks = new List<Task>();
    foreach (string templateName in templateNames)
    {
        string localTemplateName = templateName;
        // Apply our logic and add to our Dictionary in a task
        Task jobTask = Task.Run(() => 
        {
            var templateCollectionEntryUri = GetTemplateCollectionEntryUri(templateCollectionUri, localTemplateName);

            var elementModelUri = GetTemplateElementModelUri(templateCollectionUri, localTemplateName);

            string[] links = new string[2] { templateCollectionEntryUri, elementModelUri };
            d.Add(localTemplateName, links);
        });

        // Add the task to our temp collection
        allTasks.Add(jobTask);
    }

    // Wait for all tasks to finish, WhenAll is non-blocking unlike WaitAll.
    await Task.WhenAll(allTasks);

    return d;
}
公共异步任务GetTemplates(字符串showName)
{
字典d=新字典();
//获取show“DemoShow”的元素集合uri
var elementCollectionUri=GetElementCollectionUri(vizServiceDocURL,showName);
var templateCollectionUri=GetTemplateCollectionUri(elementCollectionUri);
var templateNames=GetListOfTemplateName(templateCollectionUri);
//从每个节目中获取名称和链接,并将其添加到词典中
//保留一份临时任务列表
列出所有任务=新建列表();
foreach(templateNames中的字符串templateName)
{
字符串localTemplateName=templateName;
//在任务中应用我们的逻辑并添加到字典中
Task jobTask=任务。运行(()=>
{
var templateCollectionEntryUri=GetTemplateCollectionEntryUri(templateCollectionUri,localTemplateName);
var elementModelUri=GetTemplateElementModelUri(templateCollectionUri,localTemplateName);
string[]links=新字符串[2]{templateCollectionEntryUri,elementModelUri};
d、 添加(localTemplateName,链接);
});
//将任务添加到我们的临时集合中
添加(作业任务);
}
//等待所有任务完成,WhenAll与WaitAll不同,它是非阻塞的。
等待任务。WhenAll(所有任务);
返回d;
}

您认为在任务中运行会加快速度,您在任务中旋转方法调用并立即等待它们,这增加了比看起来主要是同步和顺序的方法所需的更多的开销。您的foreach循环当然可以将作业旋转为任务,然后将这些任务添加到列表中,并使用
wait Task.WhenAll(listOfTasks)等待所有任务在循环之外,或者使用
并行。ForEach
这是一种阻塞操作。同意@ColinM,您将在线程池上调度多达80*2个基本上是连续的操作…它们可能需要相互等待。只需按顺序完成工作,或者编写一些您正在等待的同步方法的真正异步版本。执行时间仍然超过一分钟。可能是我调用它的方式<代码>字典l=await Task.Run(()=>(即GetTemplates(“MyShow”)
如果只在WPF应用程序中发生,我建议您进行性能评测,并查看大部分时间都花在哪里。谢谢!我将看一看性能评测。没有其他代码,因为当我创建了一个新的WPF应用程序时,代码很少。因此,我只添加了一个按钮,并使用前面注释中的代码调用此方法,并在函数的末尾放置一个断点a。
public async Task<Dictionary<string, string[]>> GetTemplates(string showName)
{
    Dictionary<string, string[]> d = new Dictionary<string, string[]>();

    // Get element collection uri of show "DemoShow"
    var elementCollectionUri = GetElementCollectionUri(vizServiceDocURL, showName);

    var templateCollectionUri = GetTemplateCollectionUri(elementCollectionUri);

    var templateNames = GetListOfTemplateName(templateCollectionUri);

    //get the name and links from each show and add them to the dictionary
    // Keep a temporary List of Tasks
    List<Task> allTasks = new List<Task>();
    foreach (string templateName in templateNames)
    {
        string localTemplateName = templateName;
        // Apply our logic and add to our Dictionary in a task
        Task jobTask = Task.Run(() => 
        {
            var templateCollectionEntryUri = GetTemplateCollectionEntryUri(templateCollectionUri, localTemplateName);

            var elementModelUri = GetTemplateElementModelUri(templateCollectionUri, localTemplateName);

            string[] links = new string[2] { templateCollectionEntryUri, elementModelUri };
            d.Add(localTemplateName, links);
        });

        // Add the task to our temp collection
        allTasks.Add(jobTask);
    }

    // Wait for all tasks to finish, WhenAll is non-blocking unlike WaitAll.
    await Task.WhenAll(allTasks);

    return d;
}