Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#线程/异步:在UI可交互的情况下在后台运行任务_C#_Wpf_Multithreading_Asynchronous - Fatal编程技术网

C#线程/异步:在UI可交互的情况下在后台运行任务

C#线程/异步:在UI可交互的情况下在后台运行任务,c#,wpf,multithreading,asynchronous,C#,Wpf,Multithreading,Asynchronous,在查看了Async/Wait和Threading之后,我仍然不确定将其应用于我的情况的正确方法。无论我尝试什么样的变体,我的UI仍然挂起,因为我似乎没有异步调用所需的函数,此外,我的解决方案实际上可能需要线程 我正在尝试做什么:我有一个WPF应用程序,上面有一个按钮,我想启动一个操作,该操作仍然允许通过UI或其他方式与程序交互。一旦满足在该功能之外确定的条件,该功能应结束。对我来说,这听起来相当标准,但我有一种感觉,我误解了一些东西,我没有正确地实施它 我现在拥有的: private async

在查看了Async/Wait和Threading之后,我仍然不确定将其应用于我的情况的正确方法。无论我尝试什么样的变体,我的UI仍然挂起,因为我似乎没有异步调用所需的函数,此外,我的解决方案实际上可能需要线程

我正在尝试做什么:我有一个WPF应用程序,上面有一个按钮,我想启动一个操作,该操作仍然允许通过UI或其他方式与程序交互。一旦满足在该功能之外确定的条件,该功能应结束。对我来说,这听起来相当标准,但我有一种感觉,我误解了一些东西,我没有正确地实施它

我现在拥有的:

private async void start_button_Click(object sender, RoutedEventArgs e)
{
    await StaticClass.MyFunction();
}

private void stop_button_Click(object sender, RoutedEventArgs e)
{
    StaticClass.stopFlag = true;
}

public static Task<int> myFunction()
{
    //Stuff Happens

    while(StaticClass.stopFlag == false)
        //Do Stuff

    //Stuff Happens

    return Task.FromResult(1) //I know this is bad, part of the reason I'm asking
}
private async void start\u按钮\u单击(对象发送方,路由目标)
{
等待StaticClass.MyFunction();
}
私有无效停止按钮单击(对象发送者,路由目标)
{
StaticClass.stopFlag=true;
}
公共静态任务myFunction()
{
//事情发生了
while(StaticClass.stopFlag==false)
//做事
//事情发生了
return Task.FromResult(1)//我知道这很糟糕,这也是我问的部分原因
}

我希望得到一些指导,如果我正在接近正确的方式和对我做错的任何洞察力。

,而不是试图使用<代码>布尔-< /代码>,你应该考虑使用内置到框架中。

基本上,您将构建一个
CancellationTokenSource
,并将
CancellationToken
传递给您的方法,该方法可用于处理取消


最后,您当前的方法永远不会脱离UI线程。您需要使用
任务。如果不想阻止UI,请运行
或类似操作将方法移动到线程池。

作为替代方法,您可以研究使用类来完成任务,您的UI将保持交互式。

您肯定没有正确实现它。您将返回一个
任务
,但仅在所有工作完成后返回

在我看来,您可能应该有一个同步方法:

然后像这样开始一项任务:

Task task = Task.Run((Action) MyFunction);
然后,如果您愿意,您可以等待该任务-尽管在您给出的示例中,这样做没有意义,因为在
wait
之后您没有做任何事情

我也同意里德的观点,使用
取消令牌将比其他地方的静态标志更干净。

你确实误解了

public static Task<int> myFunction()
{
    //Stuff Happens

    while(StaticClass.stopFlag == false)
        //Do Stuff

    //Stuff Happens

    return Task.FromResult(1) //I know this is bad, part of the reason I'm asking
}

好的!给Karoly一些其他的提示,这有助于我区分这一点:因为很多资料都说“…等待开始一条新的线索…”人们认为等待完成了所有神奇的事情。它帮助我把wait看作一个助手函数,让我不必为等待结果而烦恼。线程仍然是规则@短跑运动员252:是吗?我没有看到任何文章声称等待开始一个新的线程。我见过有人认为它是真的,但没有真正的消息来源声称它是真的。好吧,现在事情变得更有意义了,谢谢乔恩!接下来的问题是,你的第二个代码段和@ScottChamberlain的第二个代码段有什么区别?您的任务是否只处理任务的返回值?如果我真的不需要返回任何东西,你的建议会改变吗?@KarolyS:没什么,真的-只是Scott将循环内联,而我将它保存在一个单独的方法中。@JonSkeet是的。我会试着找一些,这样你就可以得到一些让你发笑的东西。一个完整的例子:
public static Task<int> myFunction()
{
    //Stuff Happens

    while(StaticClass.stopFlag == false)
        //Do Stuff

    //Stuff Happens

    return Task.FromResult(1) //I know this is bad, part of the reason I'm asking
}
public static async Task myFunction()
{
    //Stuff Happens on the original UI thread

    await Task.Run(() => //This code runs on a new thread, control is returned to the caller on the UI thread.
    {
        while(StaticClass.stopFlag == false)
            //Do Stuff
    });

    //Stuff Happens on the original UI thread after the loop exits.
}