Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.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# WPF:如何在UI线程中进行异步调用_C#_Wpf_Multithreading_Xaml - Fatal编程技术网

C# WPF:如何在UI线程中进行异步调用

C# WPF:如何在UI线程中进行异步调用,c#,wpf,multithreading,xaml,C#,Wpf,Multithreading,Xaml,我在xaml中有一个按钮,它的鼠标点击连接到一个委托命令。在delegate命令中,我调用另一个方法来创建位图并将其保存为pdf。此方法需要几秒钟(通常超过10秒)的时间,在此期间,应用程序进入不响应状态,用户界面不可访问。在此期间,我想展示一些已经在xaml中定义的动画。但是,在调用耗时函数之前显示它,然后隐藏它是行不通的。如果我不使用不同的线程,它会在函数执行的时间结束时显示 因此,我尝试创建一个不同的线程并调用这个计时函数。动画加载很好,但函数实际上需要访问UI线程中的一些UI对象。它会导

我在xaml中有一个按钮,它的鼠标点击连接到一个委托命令。在delegate命令中,我调用另一个方法来创建位图并将其保存为pdf。此方法需要几秒钟(通常超过10秒)的时间,在此期间,应用程序进入不响应状态,用户界面不可访问。在此期间,我想展示一些已经在xaml中定义的动画。但是,在调用耗时函数之前显示它,然后隐藏它是行不通的。如果我不使用不同的线程,它会在函数执行的时间结束时显示

因此,我尝试创建一个不同的线程并调用这个计时函数。动画加载很好,但函数实际上需要访问UI线程中的一些UI对象。它会导致以下异常: “调用线程无法访问此对象,因为其他线程拥有它。”

有没有办法做到这一点?i、 例如,在此函数执行期间显示动画

一些代码片段:

private void OnExportPDFCommand()
    {
        PanelLoading = true;  // Flag to show animation
        Task.Factory.StartNew(() =>
            {
                CreatePDF();  //time-taking-function
                Application.Current.Dispatcher.Invoke(() => PanelLoading = false);
            });
    }

请举例说明。我是WPF的新手。谢谢。

您可以将
OnExportPDFCommand
设置为
async
方法,然后
等待
您启动的
任务

private async void OnExportPDFCommand()
{
    PanelLoading = true;  // Flag to show animation
    await Task.Run(() =>
    {
            CreatePDF();  //time-taking-function
    });
    PanelLoading = false; // stop animation
}
编译器将其转换为状态机。控制流在
wait
关键字处返回给调用者(UI)。当
任务
完成时,执行最终会在下一条语句
panelload=false
中恢复

这样,对
PanelLoading
的调用将再次出现在UI线程中,不应引发任何异常

如果需要对UI进行其他调用(在
CreatePDF
中),可以使用
Application.Current.Dispatcher.Invoke(…)
在UI线程上调用这些调用



作为旁注:您可能希望禁用在
OnExportPDFCommand()
开头启动此操作的按钮,然后在结尾再次启用它。这样可以避免多次启动操作并与动画混淆。

您可以将
OnExportPDFCommand
设置为
async
方法,并
等待
您启动的
任务

private async void OnExportPDFCommand()
{
    PanelLoading = true;  // Flag to show animation
    await Task.Run(() =>
    {
            CreatePDF();  //time-taking-function
    });
    PanelLoading = false; // stop animation
}
编译器将其转换为状态机。控制流在
wait
关键字处返回给调用者(UI)。当
任务
完成时,执行最终会在下一条语句
panelload=false
中恢复

这样,对
PanelLoading
的调用将再次出现在UI线程中,不应引发任何异常

如果需要对UI进行其他调用(在
CreatePDF
中),可以使用
Application.Current.Dispatcher.Invoke(…)
在UI线程上调用这些调用



作为旁注:您可能希望禁用在
OnExportPDFCommand()
开头启动此操作的按钮,然后在结尾再次启用它。通过这种方式,您可以避免多次启动操作并与动画混淆。

@vinmm作为旁白。
boolpanelloading
模式可能不是一个好主意。如果多次调用
OnExportPDFCommand()
,则可能会出现与
panelload
标志相关的意外行为。最好将
bool PanelLoading
替换为int,您可以使用
interlocted.Increment
interlocted.Decrement
替换为。@Rene Vogt:我已经为您提到的旁注设置了标记。谢谢但我还是有问题。createPDF函数有许多对UI对象的引用(在许多地方都是如此),因为它是一个处理位图和文件的繁重操作。因此,将调用添加到所有许多地方将是困难的。有没有更好的替代方案谢谢你的片段。@vinmm我个人喜欢这种方法,但这也意味着要改变所有这些地方。如果您直接从该方法访问UI,我想不出一个解决方案不需要更改所有这些位置。@vinmm一个更好的
Progress
:是的。这就是问题所在。我的函数使用了UI中的许多内容:(.感谢您提供的所有信息。@vinmm作为旁白。
bool panelload
模式可能不是一个好主意。如果您调用
OnExportPDFCommand()
多次,您可能会出现与
面板加载
标志相关的意外行为。最好将
bool panelload
替换为int,您可以使用
interlocted.Increment
interlocted.decreation
。@Rene Vogt:我已经为您提到的s旁注。谢谢。但我仍然有问题。createPDF函数有很多对UI对象的引用(实际上在很多地方)因为这是一个处理位图和文件的繁重操作。因此,将调用添加到所有许多位置会很困难。有没有更好的替代方法?&谢谢你的代码片段。@vinmm我个人喜欢这种方法,但这意味着也要更改所有这些位置。如果你直接从该方法访问UI,我想不出一个解决方案不需要更改所有这些位置。@vinmm一个更好的
进度链接
:是的。这就是问题所在。我的函数使用了UI中的许多内容。:。感谢您提供的所有信息。