首页 新闻 会员 周边 捐助

Delegate利用委托,将方法作参数传值,并且接收返回值, 我该怎么写?

0
悬赏园豆:40 [已解决问题] 解决于 2013-10-21 13:16
 1    int iOverTime = 100000;//int.Parse(iniFile.GetString("CATCH", "OVERTIME", ""));//读取超时时间,默认10秒=100000
 2                     bValue = XCommon.OverTimeCntrol.CallFuncThread(GetArticlePageContent, TimeSpan.FromMilliseconds(iOverTime), null);
 3 
 4                     if (!bValue)
 5                     {
 6                         strStatus = "读取网址超时(" + iOverTime / 1000 + "秒),跳过!";
 7                     }
 8                     else
 9                     {
10 ......
11 }

public static void GetArticlePageContent()
{

}

 

我要传值进GetArticlePageContent方法和接收它的返回值。 该怎么写?

 

 

 1     public class OverTimeCntrol
 2     {
 3         public delegate void Delegate();
 4 
 5         /// <summary>
 6         /// 执行指定的方法,如果在指定的时间之内没有完成,则中止
 7         /// </summary>
 8         /// <param name="func">任务过程</param>
 9         /// <param name="timeSpan">超时时间</param>
10         /// <param name="timeoutCallback">如果超时,则调用该方法</param>
11         /// <returns>是否正确执行完毕</returns>
12         public static bool CallFuncThread(Delegate func, TimeSpan timeSpan, Delegate timeoutCallback)
13         {
14             if (func == null)
15                 throw new ArgumentNullException("func");
16 
17             ManualResetEvent resetEvent = new ManualResetEvent(false);
18             ManualResetEvent waitThreadEvent = new ManualResetEvent(false);
19 
20             Exception error = null;
21             Thread thread = null;
22 
23             // 将任务加到线程当中
24             ThreadPool.QueueUserWorkItem(delegate
25             {
26 
27                 thread = Thread.CurrentThread;
28                 try { func(); }
29                 catch (ThreadAbortException) { }
30                 catch (Exception ex) { error = ex; }
31 
32                 resetEvent.Set();
33                 waitThreadEvent.WaitOne();  // 每次线程执行结束都等待后续的处理逻辑
34             });
35 
36             try
37             {
38                 bool result = resetEvent.WaitOne(timeSpan, false);  // 等待任务的结束
39 
40                 if (error != null)  // 说明在执行过程中出现异常,直接抛出异常
41                     throw error;
42 
43                 if (!result)
44                 {
45                     if (thread != null)
46                     {
47                         thread.Abort();  // 此时可以确保该线程没有开始运行新的任务
48                         waitThreadEvent.Set();
49                     }
50 
51                     if (timeoutCallback != null)
52                         timeoutCallback();
53                 }
54 
55                 return result;
56             }
57             finally
58             {
59                 waitThreadEvent.Set();  // 最后确保释放线程池线程
60             }
61         }
62     }
问天何必的主页 问天何必 | 老鸟四级 | 园豆:3311
提问于:2013-10-16 09:14
< >
分享
最佳答案
0

这种用法,能获取返回值吗?我增加了你的代码,你看看是否满足需求:

internal class Program
    {
        public static void Main(string[] args)
        {
            int iOverTime = 10000;//int.Parse(iniFile.GetString("CATCH", "OVERTIME", ""));//读取超时时间,默认10秒=100000
            bool bValue = OverTimeCntrol.CallFuncThread(GetArticlePageContent, TimeSpan.FromMilliseconds(iOverTime), null, new object[] { "0", "bbb" });
            Console.ReadKey(true);
        }

        public static bool GetArticlePageContent(params object[] args)
        {
            Thread.Sleep(1000);
            return true;
        }
    }

    public class OverTimeCntrol
    {
        //记录返回值
        public static object ReturnVal { get; private set; }

        public delegate bool Delegate(object[] args);//修改委托,使之可以传入参数

        /// <summary>
        /// 执行指定的方法,如果在指定的时间之内没有完成,则中止
        /// </summary>
        /// <param name="func">任务过程</param>
        /// <param name="timeSpan">超时时间</param>
        /// <param name="timeoutCallback">如果超时,则调用该方法</param>
        /// <param name="args">任务过程所需参数</param>
        /// <returns>是否正确执行完毕</returns>
        public static bool CallFuncThread(Delegate func, TimeSpan timeSpan, Action timeoutCallback, params object[] args)
        {
            ReturnVal = null;//清空返回值。
            if (func == null)
                throw new ArgumentNullException("func");

            ManualResetEvent resetEvent = new ManualResetEvent(false);
            ManualResetEvent waitThreadEvent = new ManualResetEvent(false);

            Exception error = null;
            Thread thread = null;

            // 将任务加到线程当中
            ThreadPool.QueueUserWorkItem(delegate
            {
                thread = Thread.CurrentThread;
                try { ReturnVal=func(args); }
                catch (ThreadAbortException) { }
                catch (Exception ex) { error = ex; }

                resetEvent.Set();
                waitThreadEvent.WaitOne();  // 每次线程执行结束都等待后续的处理逻辑
            });

            try
            {
                bool result = resetEvent.WaitOne(timeSpan, false);  // 等待任务的结束

                if (error != null)  // 说明在执行过程中出现异常,直接抛出异常
                    throw error;

                if (!result)
                {
                    if (thread != null)
                    {
                        thread.Abort();  // 此时可以确保该线程没有开始运行新的任务
                        waitThreadEvent.Set();
                    }

                    if (timeoutCallback != null)
                        timeoutCallback();
                }

                return result;
            }
            finally
            {
                waitThreadEvent.Set();  // 最后确保释放线程池线程
            }
        }
    }

红色部分,是变化的。

收获园豆:40
幻天芒 | 高人七级 |园豆:37207 | 2013-10-16 14:13
其他回答(2)
0

不用把委托传进去,委托本身就是一个类,你在类中定义委托后,把方法赋给委托,然后在CallFuncThread方法中调用委托就行了大致如下

public delegate void Delegate;

Delegate delegate = methodName;

public static bool CallFuncThread(TimeSpan timeSpan)

{

  //一些操作完成后,开始调用委托中的方法

  delegate;

}

Zery | 园豆:6151 (大侠五级) | 2013-10-16 12:15

亲爱的能不能详细点啊。。。 

 

我的意思是model传值进:GetArticlePageContent这个方法, 并且接收GetArticlePageContent方法的返回值。

 

 

bool bValue=false;
  bValue= XCommon.OverTimeCntrol.CallFuncThread(GetArticlePageContent(model), TimeSpan.FromMilliseconds(iOverTime), null);  
//CallFuncThread函数会返回一个bool值, 中间的//GetArticlePageContent方法也要返回值; model是要传进去的。。。。这一步就不知道怎么写了。 用out,ref之类的全都有问题。

 

 

支持(0) 反对(0) 问天何必 | 园豆:3311 (老鸟四级) | 2013-10-16 12:26

@问天何必: 

是不是就是想把一个方法传给委托然后把委托传到CallFuncThread()这个方法中?

如果 是也好处理啊,定义一个有返回值,有接收参数的委托

public delegate bool Delegate(Model  model);

Delegate delegate = GetArticlePageContent;

再把委托传到 CallFuncThread(delegate ,model)并在方法中调用

delegate(model)

这样就OK了 

支持(0) 反对(0) Zery | 园豆:6151 (大侠五级) | 2013-10-16 12:46
0

定义一个具有返回值和参数的委托.Func<>就可以吧

平常心队长 | 园豆:1113 (小虾三级) | 2013-10-17 08:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册