求助~~多线程问题!用多个线程调用一个方法!

时间:2021-04-18 18:09:47

for (int i = 0; i < fenye.Rows.Count; i++)
            {
                string Zurl = fenye.Rows[i][0].ToString();
                string fenlei = fenye.Rows[i][1].ToString();
                SingerInFo(Zurl,fenlei);//如何用多线程调用此方法?

            }

求解~

29 个解决方案

#1


 例如,看以下的代码段。在这个例子中,Instructors类的GetPhotos方法在一个独立的线程上执行。这个方法(没有显示)向数据库查询全部的教师图象,并且将每幅图象以文件的方式保存下来,在这里,数据库访问和文件访问在一个分开的线程上执行。

Dim tPhoto As Thread
Dim tsStart As ThreadStart
Dim objIns As New Instructors

tsStart = New ThreadStart(AddressOf objIns.GetPhotos)
tPhoto = New Thread(tsStart)

tPhoto.Priority = ThreadPriority.BelowNormal
tPhoto.Name = "SavingPhotos"

tPhoto.Start()

' Wait for the started thread to become alive
While (tPhoto.ThreadState = ThreadState.Unstarted)
 Thread.Sleep(100)
End While

...

If tPhoto.IsAlive Then
 MsgBox("Still processing images...")
 MsgBox("Waiting to finish processing images...")
 tPhoto.Join
End If

MsgBox("Done processing images.")

#2


只要有一条记录就启动一个线程?

#3


抄一段给你:

提起多线程,不得不提起 委托(delegates)这个概念.

我理解的委托就是 具有 同样参数和返回值 的函数的集合.
比如
public delegate void MyDelegate(int arg);
就是这种形式的函数 void Myfuntion(int i); 的集合.
如何将一个函数加入 委托 的集合?
MyDelegate dele = new MyDelegate(Myfuntion1);
再增加一个
dele += new MyDelegate(Myfuntion2);
...
委托函数 dele 就是 具有整数参数和空返回值的函数 Myfuntion1,2的集合.
调用这个委托函数
dele(1);
就是逐个调用 Myfuntion1,2,...

一般线程函数的声明和启动

Thread t = new Thread(new ThreadStart(MyFunction));
t.Start();
正是调用了没有参数和返回值的 委托函数 ThreadStart
其中的参数MyFunction 是 这个委托函数中的一员.

很明显 这样无法传参数和返回值,那我们该怎么办?

答案就在委托 的BeginInvoke() 方法上, BeginInvoke() 也是(异步)启动一个新线程.
例如
MyDelegate dele = new MyDelegate (MyFunction);
dele.BeginInvoke(10,"abcd");
void MyFunction(int count, string str);
可以实现参数的传递.

如何收集线程函数 的 返回值?

与 BeginInvoke 对应 有个 EndInvoke 方法,而且运行完毕返回 IAsyncResult 类型的返回值.
这样我们可以这样收集 线程函数的 返回值

MyDelegate dele = new MyDelegate (MyFunction);
IAsyncResult ref = dele.BeginInvoke(10,"abcd");
...
int result = dele.EndInvoke(ref); <----收集 返回值
int MyFunction(int count, string str); <----带参数和返回值的 线程函数

#4


不需要考虑到并发访问的问题吗?

#5


线程池?
应该是不调用,是启动了。

#6


引用 2 楼 wangxiao2008 的回复:
只要有一条记录就启动一个线程?

不是每10条记录启用一个

#7


10条10个进程直到fenye.Rows.Count完

#8


引用 4 楼 guyehanxinlei 的回复:
不需要考虑到并发访问的问题吗?

大概10秒一个线程吧

#9



ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod);
Thread myThread = new Thread(SingerInFo);
object o;  // 楼主需要两个参数,可以放在一个结构进而
myThread.Start(o);

//ThreadMethod如下:
public void SingerInFo(object ParObject)
{
    //程序代码
}

#10


把SingerInFo(Zurl,fenlei);改成
Invoke((Action)delegate() { SingerInFo(Zurl,fenlei); });
就支持多线程调用,请确保SingerInFo这个方法是线程安全的。

#11


看了n个例子~~老是晕晕的!都不知道怎么弄了!求代码!

#12


纠正一下..

ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
object o;
myThread.Start(o);

//ThreadMethod如下:
public void SingerInFo(object ParObject)
{
    //程序代码
}

#13


可以考虑异步的写法:
           for (int i = 0; i < fenye.Rows.Count; i++)
            {
                string Zurl = fenye.Rows[i][0].ToString();
                string fenlei = fenye.Rows[i][1].ToString();
                ProcHandler proc = new ProcHandler(SingerInFo);
                proc.BeginInvoke(Zurl,fenlei, new AsyncCallback(OnDownloadComplete), null);
            }

       private delegate bool ProcHandler(string Zurl,string fenlei);
       private void OnDownloadComplete(IAsyncResult result)
        {
            AsyncResult resultObject = (AsyncResult)result;
            ProcHandler proc = (ProcHandler)resultObject.AsyncDelegate;
            try
            {
                proc.EndInvoke(result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

#14


我一个测试程序里 用的线程池

            OPLSessionLinkTable theSessoins = new OPLSessionLinkTable();

            int maxThreadNum, portThreadNum;
            int minThreadNum;
            ThreadPool.SetMaxThreads(40,20);
            ThreadPool.SetMinThreads(4, 2);
            ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
            ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
            theSessoins.TheSessonTimeOut = 1000;
            Console.WriteLine("最大线程数:{0}", maxThreadNum);
            Console.WriteLine("最小空闲线程数:{0}", minThreadNum);

            Console.WriteLine("启动线程池任务:");
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc1), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc2), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc3), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc4), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc5), theSessoins);

#15


Proc1,到5是不同的方法,你也可以调同一个方法。

#16


引用 12 楼 hyblusea 的回复:
纠正一下..

C# code

ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
object o;//这个是用实体的方式传参?
myThread.Start(o);

//ThreadMethod如下:
public ……

object o;//这个是用实体的方式传参?

#17



ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
List<string> o = new List<string>();
o.add(...);
o.add(...);
myThread.Start(o);

//ThreadMethod
public void SingerInFo(object ParObject)
{
}

#18


引用 13 楼 wangxiao2008 的回复:
可以考虑异步的写法:
  for (int i = 0; i < fenye.Rows.Count; i++)
  {
  string Zurl = fenye.Rows[i][0].ToString();
  string fenlei = fenye.Rows[i][1].ToString();
  ProcHandler proc = new ProcHandler(Singer……

异步操作和多线程有什么区别

#19


异步操作是由系统自动在系统线程池中分配的线程,你是不用参于线程的调度的。当你的应用涉及多线程之间的同步的时侯就不适合用异步了。

#20


异步是由.net系统来在后台做工作,做完后回调代码
多线程式针对同步完成多项任务。不管其它的事情了
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();

#21


引用 19 楼 hwbox 的回复:
异步操作是由系统自动在系统线程池中分配的线程,你是不用参于线程的调度的。当你的应用涉及多线程之间的同步的时侯就不适合用异步了。

异步的方法报错啊!说WebClient不支持并发i/o操作

#22


你在异步方法中使用了同一个webClient对象吗?试下在异步方法中创建新的webClient对象。而不是用同一个。另外,麻烦帮我顶下贴。我也有问题没太解决。

http://topic.csdn.net/u/20100714/15/6d6115dd-202b-4dba-ac76-b2899573fa06.html?48287

#23


引用 20 楼 wuyq11 的回复:
异步是由.net系统来在后台做工作,做完后回调代码
多线程式针对同步完成多项任务。不管其它的事情了
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();

大大的这个需不需要关闭代码?

#24


你可以在线程外面试着去关闭它,如果你不关闭线程运行完了自己也就释放了,如果线程没运行完,你可以在创建时把他定义成后台线程。则在进程关闭时,会被强制关闭。

谢谢帮我顶贴。

#25


该回复于2010-07-27 15:42:25被版主删除

#26


关注中

#27


我不会啊!!!!!!

#28


我不会啊!!!!!!

#29


我不会啊!!!!!!

#1


 例如,看以下的代码段。在这个例子中,Instructors类的GetPhotos方法在一个独立的线程上执行。这个方法(没有显示)向数据库查询全部的教师图象,并且将每幅图象以文件的方式保存下来,在这里,数据库访问和文件访问在一个分开的线程上执行。

Dim tPhoto As Thread
Dim tsStart As ThreadStart
Dim objIns As New Instructors

tsStart = New ThreadStart(AddressOf objIns.GetPhotos)
tPhoto = New Thread(tsStart)

tPhoto.Priority = ThreadPriority.BelowNormal
tPhoto.Name = "SavingPhotos"

tPhoto.Start()

' Wait for the started thread to become alive
While (tPhoto.ThreadState = ThreadState.Unstarted)
 Thread.Sleep(100)
End While

...

If tPhoto.IsAlive Then
 MsgBox("Still processing images...")
 MsgBox("Waiting to finish processing images...")
 tPhoto.Join
End If

MsgBox("Done processing images.")

#2


只要有一条记录就启动一个线程?

#3


抄一段给你:

提起多线程,不得不提起 委托(delegates)这个概念.

我理解的委托就是 具有 同样参数和返回值 的函数的集合.
比如
public delegate void MyDelegate(int arg);
就是这种形式的函数 void Myfuntion(int i); 的集合.
如何将一个函数加入 委托 的集合?
MyDelegate dele = new MyDelegate(Myfuntion1);
再增加一个
dele += new MyDelegate(Myfuntion2);
...
委托函数 dele 就是 具有整数参数和空返回值的函数 Myfuntion1,2的集合.
调用这个委托函数
dele(1);
就是逐个调用 Myfuntion1,2,...

一般线程函数的声明和启动

Thread t = new Thread(new ThreadStart(MyFunction));
t.Start();
正是调用了没有参数和返回值的 委托函数 ThreadStart
其中的参数MyFunction 是 这个委托函数中的一员.

很明显 这样无法传参数和返回值,那我们该怎么办?

答案就在委托 的BeginInvoke() 方法上, BeginInvoke() 也是(异步)启动一个新线程.
例如
MyDelegate dele = new MyDelegate (MyFunction);
dele.BeginInvoke(10,"abcd");
void MyFunction(int count, string str);
可以实现参数的传递.

如何收集线程函数 的 返回值?

与 BeginInvoke 对应 有个 EndInvoke 方法,而且运行完毕返回 IAsyncResult 类型的返回值.
这样我们可以这样收集 线程函数的 返回值

MyDelegate dele = new MyDelegate (MyFunction);
IAsyncResult ref = dele.BeginInvoke(10,"abcd");
...
int result = dele.EndInvoke(ref); <----收集 返回值
int MyFunction(int count, string str); <----带参数和返回值的 线程函数

#4


不需要考虑到并发访问的问题吗?

#5


线程池?
应该是不调用,是启动了。

#6


引用 2 楼 wangxiao2008 的回复:
只要有一条记录就启动一个线程?

不是每10条记录启用一个

#7


10条10个进程直到fenye.Rows.Count完

#8


引用 4 楼 guyehanxinlei 的回复:
不需要考虑到并发访问的问题吗?

大概10秒一个线程吧

#9



ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod);
Thread myThread = new Thread(SingerInFo);
object o;  // 楼主需要两个参数,可以放在一个结构进而
myThread.Start(o);

//ThreadMethod如下:
public void SingerInFo(object ParObject)
{
    //程序代码
}

#10


把SingerInFo(Zurl,fenlei);改成
Invoke((Action)delegate() { SingerInFo(Zurl,fenlei); });
就支持多线程调用,请确保SingerInFo这个方法是线程安全的。

#11


看了n个例子~~老是晕晕的!都不知道怎么弄了!求代码!

#12


纠正一下..

ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
object o;
myThread.Start(o);

//ThreadMethod如下:
public void SingerInFo(object ParObject)
{
    //程序代码
}

#13


可以考虑异步的写法:
           for (int i = 0; i < fenye.Rows.Count; i++)
            {
                string Zurl = fenye.Rows[i][0].ToString();
                string fenlei = fenye.Rows[i][1].ToString();
                ProcHandler proc = new ProcHandler(SingerInFo);
                proc.BeginInvoke(Zurl,fenlei, new AsyncCallback(OnDownloadComplete), null);
            }

       private delegate bool ProcHandler(string Zurl,string fenlei);
       private void OnDownloadComplete(IAsyncResult result)
        {
            AsyncResult resultObject = (AsyncResult)result;
            ProcHandler proc = (ProcHandler)resultObject.AsyncDelegate;
            try
            {
                proc.EndInvoke(result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

#14


我一个测试程序里 用的线程池

            OPLSessionLinkTable theSessoins = new OPLSessionLinkTable();

            int maxThreadNum, portThreadNum;
            int minThreadNum;
            ThreadPool.SetMaxThreads(40,20);
            ThreadPool.SetMinThreads(4, 2);
            ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
            ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
            theSessoins.TheSessonTimeOut = 1000;
            Console.WriteLine("最大线程数:{0}", maxThreadNum);
            Console.WriteLine("最小空闲线程数:{0}", minThreadNum);

            Console.WriteLine("启动线程池任务:");
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc1), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc2), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc3), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc4), theSessoins);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Proc5), theSessoins);

#15


Proc1,到5是不同的方法,你也可以调同一个方法。

#16


引用 12 楼 hyblusea 的回复:
纠正一下..

C# code

ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
object o;//这个是用实体的方式传参?
myThread.Start(o);

//ThreadMethod如下:
public ……

object o;//这个是用实体的方式传参?

#17



ParameterizedThreadStart ParStart = new ParameterizedThreadStart(SingerInFo);
Thread myThread = new Thread(ParStart);
List<string> o = new List<string>();
o.add(...);
o.add(...);
myThread.Start(o);

//ThreadMethod
public void SingerInFo(object ParObject)
{
}

#18


引用 13 楼 wangxiao2008 的回复:
可以考虑异步的写法:
  for (int i = 0; i < fenye.Rows.Count; i++)
  {
  string Zurl = fenye.Rows[i][0].ToString();
  string fenlei = fenye.Rows[i][1].ToString();
  ProcHandler proc = new ProcHandler(Singer……

异步操作和多线程有什么区别

#19


异步操作是由系统自动在系统线程池中分配的线程,你是不用参于线程的调度的。当你的应用涉及多线程之间的同步的时侯就不适合用异步了。

#20


异步是由.net系统来在后台做工作,做完后回调代码
多线程式针对同步完成多项任务。不管其它的事情了
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();

#21


引用 19 楼 hwbox 的回复:
异步操作是由系统自动在系统线程池中分配的线程,你是不用参于线程的调度的。当你的应用涉及多线程之间的同步的时侯就不适合用异步了。

异步的方法报错啊!说WebClient不支持并发i/o操作

#22


你在异步方法中使用了同一个webClient对象吗?试下在异步方法中创建新的webClient对象。而不是用同一个。另外,麻烦帮我顶下贴。我也有问题没太解决。

http://topic.csdn.net/u/20100714/15/6d6115dd-202b-4dba-ac76-b2899573fa06.html?48287

#23


引用 20 楼 wuyq11 的回复:
异步是由.net系统来在后台做工作,做完后回调代码
多线程式针对同步完成多项任务。不管其它的事情了
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();
new Thread((ThreadStart)delegate { SomeMethod(); }).Start();

大大的这个需不需要关闭代码?

#24


你可以在线程外面试着去关闭它,如果你不关闭线程运行完了自己也就释放了,如果线程没运行完,你可以在创建时把他定义成后台线程。则在进程关闭时,会被强制关闭。

谢谢帮我顶贴。

#25


该回复于2010-07-27 15:42:25被版主删除

#26


关注中

#27


我不会啊!!!!!!

#28


我不会啊!!!!!!

#29


我不会啊!!!!!!