C#开了线程仍然卡

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#开了线程仍然卡相关的知识,希望对你有一定的参考价值。

我的这个方法放进线程界面仍然会卡死,用异步委托也一样卡.
public void reqWeb()

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.qq.com");
request.Method = "get";
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream())

using (StreamReader sr = new StreamReader(stream))

textBox1.Text = sr.ReadToEnd();
showTxt();


参考技术A

看起来你的reqWeb并没有放在后台线程中运行。不然textBox1.Text = sr.ReadToEnd(); 这句在.net 2及以后会报异常的。应该是这个函数比较耗时,所以界面需要等该函数返回才会有响应。

把这句函数放在BackgroundWorker中或是创建一个线程运行,然后'textBox1.Text = sr.ReadToEnd(); '就不能直接使用了。还有可以不使用WebRequest的。

象下面这样

Thread thread= new Thread(reqWeb);
thread.IsBackground = true;

thread.Start();


    private static void reqWeb()
    
        var client = new WebClient();
        var str = client.DownloadString(@"www.qq.com");
        MethodInvoker invoker = () =>  textBox1.Text = str; ;
        if (textBox1.InvokeRequired)
            textBox1.Invoke(invoker);
        else
            invoker();
    

参考技术B 问题可能出在showTxt()方法上,UI不能跨线程访问,如果你只是执行这么个方法,可以用 BackgroundWorker在后台处理, RunWorkerCompleted事件中再showTxt();
欢迎追问。追问

不是showTxt()的问题,我删了,一样卡,我用的就是后台线程

追答

介意看看吗 2237638653

参考技术C 操作界面自然是UI进程卡住了

unity c#跨线程调用怎么实现

在unity里边使用多线程做一些事情是非常好的,比如解压资源 更新资源等。因为单开线程的话 不会影响主线程卡顿,这样UI就不会卡了。但是开的线程里边不能执行unity主线程的mono代码。线程启动后,执行完毕自动结束该线程、可以同时启动多个线程做事。
代码如下: using System.Threading;
void StartThread()


Thread athread = new Thread(new ThreadStart(goThread));
athread.IsBackground = true;//防止后台现成。相反需要后台线程就设为false

athread.Start();

void Awake()

StartThread();

object lockd = new object();
void goThread()

int index = 0;
while (true)

lock (lockd)//防止其他线程访问当前线程使用的数据

Debug.Log("in thread" + index);
index++;
if (index == 100)

Thread.Sleep(10000);// 将当前线程挂起指定的时间 毫秒 时间结束后 继续执行下一步 和yield类似

else if (index == 200)

break;//该函数执行完自动结束该线程





所以其实多线程和协程原理差别很大的,只是功能有点类似。

1、当在主线程中创建了一个线程,那么该线程的IsBackground默认是设置为FALSE的。
2、当主线程退出的时候,IsBackground=FALSE的线程还会继续执行下去,直到线程执行结束。
3、只有IsBackground=TRUE的线程才会随着主线程的退出而退出
---------------------------------------------------------------------------------------------

ThreadStart:
Thread athread = new Thread(new ThreadStart(goThread));
athread.Start();//该方法启动的多线程 不能带有参数。

ParameterThreadStart:

ParameterThreadStart的定义为void ParameterizedThreadStart(object state),使用这个这个委托定义的线程的启动函数可以接受一个输入参数,具体例子如下 :
[csharp] view plain copy
ParameterizedThreadStart threadStart=new ParameterizedThreadStart(Calculate)
Thread thread=new Thread() ;
thread.Start(0.9);//参数是0.9
public void Calculate(object arg)//arg参数是0.9

double Diameter=double(arg);
Console.Write("The Area Of Circle with a Diameter of 0 is 1"Diameter,Diameter*Math.PI);

Calculate方法只有一个为object类型的参数。需要传多个参数的时候 需要把参数都塞进object 然后进行转换。比如:

一个参数 void BuildA(object para) List<int> list=para as List<int>;...
BuildA(list);
多个参数 void BuildB(object para) object[] ps= para as object[];List<int> list=ps[0] as as List<int>;GameObject b=ps[1] as GameObject;...
BuildB(new object[]list,obj);//把多个参数塞到object数组里边 传过去,相当于只传一个参数。

至于是开一个线程还是多个线程 根据需求和内核数SystemInfo.processorCount来确定。最好一个核开一个线程 会快点。
详见bundleglobal.cs和sdFileSystem.cs/sdMultiThread.cs
参考技术A unity中 必须在unity的主线程下进行工作 如果一定要使用其他线程的话 只有将其他线程作的操作存入队列 等待unity中的update方法中去读取队列

以上是关于C#开了线程仍然卡的主要内容,如果未能解决你的问题,请参考以下文章

c# 多线程运行时出现主界面卡死现象如何解决?

c# 多线程互斥问题。。

C# 如何获取当前方法所在的线程?

unity c#跨线程调用怎么实现

为啥 log4net 线程卡在等待中?

线程和进程有什么区别?