方法执行时间过长,界面卡死

varlj 2008-07-17 02:38:22
这几天一直在做FTP的东东,现在碰到一个问题,在调用下载或上传方法时,会长时间的使界面没有反应,我的代码大概如下:

public delegate void ThreadSafe();

//用于下载,同时也会更新TaskView
private void Download()
{
//下载,会一直阻塞直到下载完成
}

//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
Thread th = new Thread(new ThreadStart(StartThread));
th.Start();
}

private void StartThread()
{
if (TaskView.InvokeRequired)
{
ThreadSafe ts = new ThreadSafe(Download);
TaskView.BeginInvoke(ts);//也试过Invoke
}
else
Download();
}


像上面的代码,下载上传是能正常完成的,但是在下载或上传过程中,整个界面是死掉的,这是为什么呢?多线程用错了?怎么一点效果也没有呢?

好困,今天早睡了,希望起床的时候大家能给我个惊喜,呵呵
...全文
462 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
numbo 2008-07-27
  • 打赏
  • 举报
回复
IAsyncResult result = TaskView.BeginInvoke(ts);//也试过Invoke
TaskView.EndInvoke(result );//调用EndInvode,确保ts函数执行,界面刷新完后,才返回。
lyx5525 2008-07-22
  • 打赏
  • 举报
回复
支持中.,,,,,
sisen 2008-07-17
  • 打赏
  • 举报
回复
问题出在这里:
private void StartThread()
{
if (TaskView.InvokeRequired)
{
ThreadSafe ts = new ThreadSafe(Download);
TaskView.BeginInvoke(ts);//也试过Invoke
}
else
Download();
}



修改成:
//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
Thread th = new Thread(new ThreadStart(StartThread));
th.IsBackground = true;
th.Start();
}


private void StartThread()
{
Download();
}
「已注销」 2008-07-17
  • 打赏
  • 举报
回复
导步下载有点麻烦,大概的过程是这样的:
private void Download()
{
BeginDown(); //开始
EndDown();//这里会传一个回调方法,因为是异步的,这个方法会马上返回而不会阴塞在那里,当下载完成之后会自动调用你 的回调方法来通知你下载完成,关于异步的例子你可以看一下MSDN,上面说的很清楚
}
大山里的松 2008-07-17
  • 打赏
  • 举报
回复
另外开启一个线程来处理就可以了
vwxyzh 2008-07-17
  • 打赏
  • 举报
回复
public delegate void ThreadSafe();

//用于下载,同时也会更新TaskView
private void Download()
{
//下载,会一直阻塞直到下载完成
}

//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
//UI线程
Thread th = new Thread(new ThreadStart(StartThread));
th.Start();
}

private void StartThread()
{
//UI线程或其他线程
if (TaskView.InvokeRequired)//如果不是在UI线程,返回true
{
//其他线程
ThreadSafe ts = new ThreadSafe(Download);
TaskView.BeginInvoke(ts);//也试过Invoke
}
else
//UI线程
Download();
}

lz的多线程等于没有,整个Download还是在UI线程里面
帮lz改一下:
public delegate void ThreadSafe();

//用于下载,同时也会调用UpdateView
private void Download()
{
//下载,会一直阻塞直到下载完成
//其他线程
//...
UpdateView()
//...
}

//更新TaskView
private void UpdateView()
{
//UI线程或其他线程
if (TaskView.InvokeRequired)//如果不是在UI线程,返回true
{
//其他线程
ThreadSafe ts = new ThreadSafe(UpdateView);
TaskView.BeginInvoke(ts);//或者用Invoke,在这里差不多
}
else
{
//UI线程,想更新什么就更新什么
TaskView.X=Y;
}
}

//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
//UI线程
Thread th = new Thread(new ThreadStart(Download));
th.Start();
}
poson 2008-07-17
  • 打赏
  • 举报
回复
开一个线程中运行。线程中运行就有同步问题了
varlj 2008-07-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 longfei_liuweitao 的回复:]
你的方法是同步的,应该用异步,这样方法才能马上返回,你的界面才不会死掉!
[/Quote]

可否说下哪里改一下?Invoke和BeginInvoke的区别?
yhy0611 2008-07-17
  • 打赏
  • 举报
回复
还是多线程吧
「已注销」 2008-07-17
  • 打赏
  • 举报
回复
你的方法是同步的,应该用异步,这样方法才能马上返回,你的界面才不会死掉!
varlj 2008-07-17
  • 打赏
  • 举报
回复
谢谢几位,我改了试试
我现在是把所有下载方法写成一个类FTP,然后就阻塞在下载方法那

private void Download()
{
if( Ftp.download("a.gif") )//就卡在这里了,因为下载是使用strem的,也试过每读一次sleep(1)
UpdateView();//更新界面的方法
}

//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
Thread th = new Thread(new ThreadStart(StartThread));
th.Start();
}

private void StartThread()
{
if (TaskView.InvokeRequired)
{
ThreadSafe ts = new ThreadSafe(Download);
ts.IsBackground = true;
TaskView.BeginInvoke(ts);//也试过Invoke
}
else
Download();
}



按照四楼的方法,是把下载和更新分开,不过我发现阻塞就阻塞在下载那个方法了,即使按照四楼的方法,下载完一个后更新界面,大概试了下,还是没效果的样子
现在有事不能仔细试,各位有什么好的意思提一下啊,谢谢了
rqx110 2008-07-17
  • 打赏
  • 举报
回复
异步咯
jin1002 2008-07-17
  • 打赏
  • 举报
回复
多线程和界面刷新问题
支持4楼
JeffChung 2008-07-17
  • 打赏
  • 举报
回复
多线程用的有问题……试试4楼的吧
mextb1860 2008-07-17
  • 打赏
  • 举报
回复
4楼好
yagebu1983 2008-07-17
  • 打赏
  • 举报
回复
调试了没有!!
gomoku 2008-07-17
  • 打赏
  • 举报
回复


//用于下载,同时也会更新TaskView
private void Download()
{
//下载,会一直阻塞直到下载完成
for (int i = 0; i < 100; i++)
{
Thread.Sleep(500); //用于下载
string str = i + "% downloaded"; //用于下载

UpdateTaskView(str); //用于更新TaskView
}
}

//开始下载
private void button1_Click(object sender, System.EventArgs e)
{
Thread th = new Thread(new ThreadStart(Download));
th.IsBackground = true;
th.Start();
}

private void UpdateTaskView( object newArrival )
{
if (TaskView.InvokeRequired)
{
TaskView.Invoke(new ParameterizedThreadStart(UpdateTaskView), newArrival);
}
else
{
TaskView.Items.Add(newArrival.ToString()); // change this line to fit your need
}
}
virusswb 2008-07-17
  • 打赏
  • 举报
回复
多线程
还可以控制线程的运行,主线程不会卡死,主界面不卡死
JustLovePro 2008-07-17
  • 打赏
  • 举报
回复
oo
changjiangzhibin 2008-07-17
  • 打赏
  • 举报
回复
试试,将支线程中运行的方法写到另一个类中

110,534

社区成员

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

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

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