簡體   English   中英

C# 線程/異步:在 UI 可交互時在后台運行任務

[英]C# Threading/Async: Running a task in the background while UI is interactable

在查看了 Async/Await 和 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
}

我希望得到一些指導,了解我是否以正確的方式處理這個問題,以及對我做錯了什么的任何見解。

你肯定是錯誤地實施了它。 您正在返回Task<int> ,但只有在所有工作都已完成之后

在我看來,您可能應該只有一個同步方法:

private static void MyFunction()
{
    // Loop in here
}

然后為它啟動一個任務,如下所示:

Task task = Task.Run((Action) MyFunction);

然后,如果您願意,您可以等待該任務 - 盡管在您給出的示例中,這樣做沒有意義,因為無論如何您在await之后都沒有做任何事情。

我也同意 Reed 的觀點,即使用CancellationToken比其他地方的靜態標志更干凈。

你誤會了。

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
}

所有這些代碼仍然發生在初始await StaticClass.MyFunction(); 調用,它永遠不會將控制權返回給調用者。 您需要做的是將循環部分放入單獨的線程中。

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.
}

您應該考慮使用框架中內置的托管取消框架,而不是嘗試為此使用bool

基本上,你會建立一個CancellationTokenSource ,並傳遞一個CancellationToken你的方法,它可以用來處理取消。

最后,您當前的方法永遠不會脫離 UI 線程。 如果您不想阻塞 UI,則需要使用Task.Run或類似方法將方法移動到 ThreadPool。

作為替代方案,您可以考慮使用BackgroundWorker類來完成這項工作,您的 UI 將保持交互。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM