WPF多线程问题求教大神解答,在线等!

顾墨笙 2013-11-18 10:15:21
小白才开始用WPF,要做一个点击当前图片然后出现一个新窗体,因为新窗体加载数据有点多,想在新窗体没有出现之前做一个loading的效果。但是对多线程了解不多也不知道WPF中的这种多线程该怎么处理。求大神指教啊啊啊啊啊啊啊啊啊啊啊啊啊啊
private void gameImage1_MouseDown(object sender, MouseButtonEventArgs e)
{
try{
ShowLoading(true);
if (image.MakerId != null)
{
string[] str=new string[]{image.MakerId,image.Banner};
thread = new Thread(new ParameterizedThreadStart(gameLaunch));
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start(str);
}

}catch{}
finally
{
ShowLoading(false);
}
}

private void gameLaunch(object obj)
{
string[] str = obj as string[];
int game = int.Parse(str[0]);
string brandName = str[1];
WindXLive wind = new WindXLive();
wind.Show();
System.Windows.Threading.Dispatcher.Run();
return;
}

private void ShowLoading(bool isShow)
{
if (isShow)
{
loading.Visibility = Visibility.Visible;
}
else
{
loading.Visibility = Visibility.Collapsed;
}
}


我现在是loading做了个用户控件,放在别的地方loading可以转动,但是放在这里可能是加载数据占用了线程,loading一直卡住不动
...全文
208 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
顾墨笙 2013-11-20
  • 打赏
  • 举报
回复
引用 19 楼 qq873113580 的回复:
例如 前台,后面记得给和夸全部的,为了显示挡住全屏的效果
<Window x:Class="WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <Grid x:Name="aaa" Grid.RowSpan="4" Visibility="Collapsed">
            
        </Grid>
    </Grid>
</Window>
UC控件

<UserControl x:Class="WPF.UC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid Height="200" Width="300">
        <Label>Loding......</Label>
    </Grid>
</UserControl>


在第一个页面的后台代码

[code=csharp]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF
{
    
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread t;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            t = new Thread(new ThreadStart(show));
            t.Start();
        }

        void show()
        {
            this.aaa.Dispatcher.Invoke(new Action(() =>
            {
                this.aaa.Children.Add(new UC());
                this.aaa.Visibility = Visibility.Visible;
            }));
            
            //相当于做其他的事情
            Thread.Sleep(3000);
            this.aaa.Dispatcher.Invoke(new Action(() =>
            {
                this.aaa.Visibility = Visibility.Collapsed;
            }));
            
            t.Abort();
        }
    }
}
[/code]
多谢,我试了下可以了!
Teln_小凯 2013-11-20
  • 打赏
  • 举报
回复
例如 前台,后面记得给和夸全部的,为了显示挡住全屏的效果
<Window x:Class="WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <Grid x:Name="aaa" Grid.RowSpan="4" Visibility="Collapsed">
            
        </Grid>
    </Grid>
</Window>
UC控件

<UserControl x:Class="WPF.UC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid Height="200" Width="300">
        <Label>Loding......</Label>
    </Grid>
</UserControl>


在第一个页面的后台代码

[code=csharp]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF
{
    
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread t;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            t = new Thread(new ThreadStart(show));
            t.Start();
        }

        void show()
        {
            this.aaa.Dispatcher.Invoke(new Action(() =>
            {
                this.aaa.Children.Add(new UC());
                this.aaa.Visibility = Visibility.Visible;
            }));
            
            //相当于做其他的事情
            Thread.Sleep(3000);
            this.aaa.Dispatcher.Invoke(new Action(() =>
            {
                this.aaa.Visibility = Visibility.Collapsed;
            }));
            
            t.Abort();
        }
    }
}
[/code]
Teln_小凯 2013-11-20
  • 打赏
  • 举报
回复
引用 17 楼 u012872853 的回复:
[quote=引用 16 楼 qq873113580 的回复:] [quote=引用 13 楼 u012872853 的回复:] [quote=引用 10 楼 qq873113580 的回复:] [quote=引用 6 楼 u012872853 的回复:] [quote=引用 4 楼 qq873113580 的回复:] LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。[/quote] 显示这部分是差不多的,做过一点WPF,这些代码够用完成你的效果[/quote] QAQ 我loading的那个是做成了用户控件,不是窗体。。这里要怎么弄啊[/quote] 那么你把他加载到一个窗体里面 F f=new F(); f.Grid.Children.Add(new 控件); f.show()[/quote]- - 做成用户控件的原因就是为了用户切换的时候吧loading切换出来。。[/quote] 如果是直接在上面打开的话 就是添加到Grid.Children.Add这里一样的..... 比如 点击 切换 一个圈圈 提示正在处理,或者什么的,道理都一样的
顾墨笙 2013-11-19
  • 打赏
  • 举报
回复
引用 16 楼 qq873113580 的回复:
[quote=引用 13 楼 u012872853 的回复:] [quote=引用 10 楼 qq873113580 的回复:] [quote=引用 6 楼 u012872853 的回复:] [quote=引用 4 楼 qq873113580 的回复:] LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。[/quote] 显示这部分是差不多的,做过一点WPF,这些代码够用完成你的效果[/quote] QAQ 我loading的那个是做成了用户控件,不是窗体。。这里要怎么弄啊[/quote] 那么你把他加载到一个窗体里面 F f=new F(); f.Grid.Children.Add(new 控件); f.show()[/quote]- - 做成用户控件的原因就是为了用户切换的时候吧loading切换出来。。
Teln_小凯 2013-11-18
  • 打赏
  • 举报
回复
引用 13 楼 u012872853 的回复:
[quote=引用 10 楼 qq873113580 的回复:] [quote=引用 6 楼 u012872853 的回复:] [quote=引用 4 楼 qq873113580 的回复:] LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。[/quote] 显示这部分是差不多的,做过一点WPF,这些代码够用完成你的效果[/quote] QAQ 我loading的那个是做成了用户控件,不是窗体。。这里要怎么弄啊[/quote] 那么你把他加载到一个窗体里面 F f=new F(); f.Grid.Children.Add(new 控件); f.show()
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 12 楼 lhx527099095 的回复:
[quote=引用 11 楼 u012872853 的回复:] [quote=引用 9 楼 lhx527099095 的回复:] 给你讲讲大概思路吧 就是你要找到你最花费时间的操作 然后把这个操作做成异步的 步骤是1在开始前显示loading 2异步执行花费事件的操作(因为是异步的 所以ui线程不会被占住 londing会转) 3.异步执行结束了,将loading结束掉 就是这么简单。。。。。。
= =我是这样做的啊,大神看下我贴出来的代码[/quote] 没怎么仔细看你的代码 只给你说下思路吧 你先把你的新窗口show出来 加载数据在新窗口的loaded事件里面去异步加载 londing也在新窗口里面 不都可以了么 何必搞这么混乱复杂呢 当然我不知道你的具体需求。。。。。[/quote]= = 我在新窗体里面异步加载数据后,在我往新窗体控件上赋值的地方都报“调用线程无法访问此对象,因为另一个线程拥有该对象“
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 12 楼 lhx527099095 的回复:
[quote=引用 11 楼 u012872853 的回复:] [quote=引用 9 楼 lhx527099095 的回复:] 给你讲讲大概思路吧 就是你要找到你最花费时间的操作 然后把这个操作做成异步的 步骤是1在开始前显示loading 2异步执行花费事件的操作(因为是异步的 所以ui线程不会被占住 londing会转) 3.异步执行结束了,将loading结束掉 就是这么简单。。。。。。
= =我是这样做的啊,大神看下我贴出来的代码[/quote] 没怎么仔细看你的代码 只给你说下思路吧 你先把你的新窗口show出来 加载数据在新窗口的loaded事件里面去异步加载 londing也在新窗口里面 不都可以了么 何必搞这么混乱复杂呢 当然我不知道你的具体需求。。。。。[/quote]大神,你是说把loading放在新窗体的最前面,然后再新窗体里面异步加载数据是么,我去试试!!
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 10 楼 qq873113580 的回复:
[quote=引用 6 楼 u012872853 的回复:] [quote=引用 4 楼 qq873113580 的回复:] LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。[/quote] 显示这部分是差不多的,做过一点WPF,这些代码够用完成你的效果[/quote] QAQ 我loading的那个是做成了用户控件,不是窗体。。这里要怎么弄啊
lhx527099095 2013-11-18
  • 打赏
  • 举报
回复
引用 11 楼 u012872853 的回复:
[quote=引用 9 楼 lhx527099095 的回复:] 给你讲讲大概思路吧 就是你要找到你最花费时间的操作 然后把这个操作做成异步的 步骤是1在开始前显示loading 2异步执行花费事件的操作(因为是异步的 所以ui线程不会被占住 londing会转) 3.异步执行结束了,将loading结束掉 就是这么简单。。。。。。
= =我是这样做的啊,大神看下我贴出来的代码[/quote] 没怎么仔细看你的代码 只给你说下思路吧 你先把你的新窗口show出来 加载数据在新窗口的loaded事件里面去异步加载 londing也在新窗口里面 不都可以了么 何必搞这么混乱复杂呢 当然我不知道你的具体需求。。。。。
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 9 楼 lhx527099095 的回复:
给你讲讲大概思路吧 就是你要找到你最花费时间的操作 然后把这个操作做成异步的 步骤是1在开始前显示loading 2异步执行花费事件的操作(因为是异步的 所以ui线程不会被占住 londing会转) 3.异步执行结束了,将loading结束掉 就是这么简单。。。。。。
= =我是这样做的啊,大神看下我贴出来的代码
Teln_小凯 2013-11-18
  • 打赏
  • 举报
回复
引用 6 楼 u012872853 的回复:
[quote=引用 4 楼 qq873113580 的回复:] LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。[/quote] 显示这部分是差不多的,做过一点WPF,这些代码够用完成你的效果
lhx527099095 2013-11-18
  • 打赏
  • 举报
回复
给你讲讲大概思路吧 就是你要找到你最花费时间的操作 然后把这个操作做成异步的 步骤是1在开始前显示loading 2异步执行花费事件的操作(因为是异步的 所以ui线程不会被占住 londing会转) 3.异步执行结束了,将loading结束掉 就是这么简单。。。。。。
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 7 楼 lhx527099095 的回复:
[quote=引用 2 楼 u012872853 的回复:] [quote=引用 1 楼 lhx527099095 的回复:] http://blog.csdn.net/lhx527099095/article/details/8005095 http://blog.csdn.net/lhx527099095/article/details/8009620 请看这两篇博客 呵呵
这个我看过,只是做出loading的效果,但是我现在是用loading的时候加载数据loading动画卡住不动[/quote] 第二篇专门讲线程的。。。。。 第一篇讲loading的啊 两个一结合就出来了么 哎[/quote]TAT.. 楼主比较白痴,第一篇还能知道,第二篇不知道怎么用 他这个是刷新界面控件值,我这个是窗体之间跳转。求具体!
lhx527099095 2013-11-18
  • 打赏
  • 举报
回复
引用 2 楼 u012872853 的回复:
[quote=引用 1 楼 lhx527099095 的回复:] http://blog.csdn.net/lhx527099095/article/details/8005095 http://blog.csdn.net/lhx527099095/article/details/8009620 请看这两篇博客 呵呵
这个我看过,只是做出loading的效果,但是我现在是用loading的时候加载数据loading动画卡住不动[/quote] 第二篇专门讲线程的。。。。。 第一篇讲loading的啊 两个一结合就出来了么 哎
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 4 楼 qq873113580 的回复:
LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
= = 感觉WPF和winform差别还是很大的。。
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 3 楼 duanzi_peng 的回复:
lz 可以把loading的效果放在单独线程上执行,因为你弹出窗口本身就执行一个操作,建议使用BackgroundWorker。我以前做过一个导出数据显示进度的,使用的是进度条,应该和你的需求差不多。
请教怎么把loading单独放在一个线程上面啊,对线程不是很熟。。
Teln_小凯 2013-11-18
  • 打赏
  • 举报
回复
LoadingForm lf; Thread t1; click(s,e) { t1=new Thread(new StartThread(Loding)); t1.Start(); //这里是你的其他新界面 F f=new F(); .... //界面处理完之后关闭当前线程 t1.Abort(); } void Loding() { lf=new LoadingForm(); lf.Show();//或者显示到你要显示的地方 } 以前做WinForm的时候我是这样弄的,WPF应该也差不多
exception92 2013-11-18
  • 打赏
  • 举报
回复
lz 可以把loading的效果放在单独线程上执行,因为你弹出窗口本身就执行一个操作,建议使用BackgroundWorker。我以前做过一个导出数据显示进度的,使用的是进度条,应该和你的需求差不多。
顾墨笙 2013-11-18
  • 打赏
  • 举报
回复
引用 1 楼 lhx527099095 的回复:
http://blog.csdn.net/lhx527099095/article/details/8005095 http://blog.csdn.net/lhx527099095/article/details/8009620 请看这两篇博客 呵呵
这个我看过,只是做出loading的效果,但是我现在是用loading的时候加载数据loading动画卡住不动
lhx527099095 2013-11-18
  • 打赏
  • 举报
回复
http://blog.csdn.net/lhx527099095/article/details/8005095 http://blog.csdn.net/lhx527099095/article/details/8009620 请看这两篇博客 呵呵

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧