C# 异步回调请问这样有意义吗

时间:2022-08-27 15:44:44
namespace ConsoleApplication1
{
    class Program
    {
        public delegate string TakesAwhileDel(int data,int ms);
        static void Main(string[] args)
        {
            TakesAwhileDel dl = TakesAwhile;
            dl.BeginInvoke(1, 6000, AsyncCallbackImpl, dl);
            System.Threading.Thread.Sleep(1000);
            Console.ReadLine();  
        }
        public static void AsyncCallbackImpl(IAsyncResult ar)
        {
            TakesAwhileDel dl = ar.AsyncState as TakesAwhileDel;
            string re = dl.EndInvoke(ar); 
            Console.WriteLine("结果{0}", re);
            //TakesAwhileDel d2 = TakesAwhile;
            dl.BeginInvoke(1, 6000, AsyncCallbackImpl, dl);
        }
        static string TakesAwhile(int data, int ms)
        {
          
            Console.WriteLine("开始调用");
            System.Threading.Thread.Sleep(ms);
            Console.WriteLine("完成调用");
            string str = "测试成功";
           

            return str;
        }  
    }
}


功能上需要不停的获取网页某一信息来判断,网上说异步比多线程性能上要好些,想这样写但感觉有点不像呢,请问这样写对吗?

16 个解决方案

#1


异步比多线程?这两者不具备可比性。

#2


高手来,我是发表不了意见了。

#3


异步本身当然是一件有重大意义的事情,比如在服务器程序中可以提高吞吐量,减少请求排队时间。
对于你当前的这个书本上的示例来说,仅是说事异步中有关回调的使用。
例子本身仅能说明回调比论询好。

#4


那么多 sleep。。有何意义?

#5


多线程可以构建异步模式,多线程是材料,异步模式是组织方式,把红木可以做成太师椅,但如果说太师椅比红木好,就有点不搭界。
推荐给你几篇文章吧
http://blog.csdn.net/etudiant6666/article/details/7449040

http://blog.sina.com.cn/s/blog_72ed17450100tx2l.html

#6


引用 5 楼  的回复:
多线程可以构建异步模式,多线程是材料,异步模式是组织方式,把红木可以做成太师椅,但如果说太师椅比红木好,就有点不搭界。
推荐给你几篇文章吧
http://blog.csdn.net/etudiant6666/article/details/7449040

http://blog.sina.com.cn/s/blog_72ed17450100tx2l.html

请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗?

#7


当然有意义了哦

#8


引用 6 楼  的回复:
请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗

开线程吧,话说你用线程还不是要用到异步

#9


异步在多并发或者防止阻塞的时候才有意义或优势

#10


引用 6 楼  的回复:
请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗?

你的目的是发现源码不同即处理,其实是有两种思路:
1.按你想的去巡检,但它影响效率。
2. 服务器发生源码变化时,向所有激活用户发通知,客户端收到通知后进行变更。
 可见,第2种方法的效率会比较高,也可以理解为异步的另一种形式,即异步的等待并处理外部命令。

#11


对于你的代码,在异步处理时,要注意尽可能少的占用时间,即通过各个线程的信号沟通,实现事物的处理。比如你发出异步任务后,就不好使用固定的等待时间(因为这样的话,你的业务处理完了,主线程还在等待,没处理完,主线程也可能强制结束了),而最好由回调函数去释放你的阻塞等待。


namespace ConsoleApplication1
{
    class Program
    {
        public delegate string TakesAwhileDel(int data,int ms);
         ManuResetEvent _BlockEvent=new ManuResetEvent(false);

        static void Main(string[] args)
        {
            TakesAwhileDel dl = TakesAwhile;
            dl.BeginInvoke(1, 6000, AsyncCallbackImpl, dl);
             _BlockEvent.WaitOne();
             Console.ReadLine();  
        }
        public static void AsyncCallbackImpl(IAsyncResult ar)
        {
            TakesAwhileDel dl = ar.AsyncState as TakesAwhileDel;
            string re = dl.EndInvoke(ar); 
            Console.WriteLine("结果{0}", re);
            _BlockEvent.Set();
        }
        static string TakesAwhile(int data, int ms)
        {
          
            Console.WriteLine("开始调用");
            System.Threading.Thread.Sleep(ms);
            Console.WriteLine("完成调用");
            string str = "测试成功";
           
            return str;
        }  
    }
}



#12


"BeginInvoke,EndInvoke"这种模式的内部实现是使用CLR内部维护的线程池。
所以你使用这种模式省去了自己创建线程并维护等等步骤

#13


异步和多线程??这两者没有可比性吧...
我想楼主想问的是 为什么要用回调函数,不用也可以实现不是吗?
的确,不用回调函数是可以实现的,可以调用的,利用IAsyncResult对象的IsCompleted属性来判断,主线程用个while语句来控制 也就是轮循方式  就可以实现了
但是 轮询方式来检测异步方法的状态很麻烦,效率又不高
如果用回调方法的话  就改善了很多了  因为 回调方法的执行不是在主线程里执行的 而是还是在异步线程里执行的  也就不会影响主线程了

#14


关于线程池的问题  最好不要运用在长时间任务的异步处理  否则长时间占用线程池的工作线程 线程池满了以后就苦了在排队的线程了  反正自己灵活运用吧

#15


引用 12 楼  的回复:
"BeginInvoke,EndInvoke"这种模式的内部实现是使用CLR内部维护的线程池。
所以你使用这种模式省去了自己创建线程并维护等等步骤

默认线程池中的上限好像是25个

#16


默认线程池中的上限
Framework2.0中最大线程默认为25*CPU数
3.0,4.0是250*CPU数
跟cpu版本也有关系吧  
可以用ThreadPool.GetAvailableThreads( out int workerThreads,out int completionPortThreads ) 来测试下

#1


异步比多线程?这两者不具备可比性。

#2


高手来,我是发表不了意见了。

#3


异步本身当然是一件有重大意义的事情,比如在服务器程序中可以提高吞吐量,减少请求排队时间。
对于你当前的这个书本上的示例来说,仅是说事异步中有关回调的使用。
例子本身仅能说明回调比论询好。

#4


那么多 sleep。。有何意义?

#5


多线程可以构建异步模式,多线程是材料,异步模式是组织方式,把红木可以做成太师椅,但如果说太师椅比红木好,就有点不搭界。
推荐给你几篇文章吧
http://blog.csdn.net/etudiant6666/article/details/7449040

http://blog.sina.com.cn/s/blog_72ed17450100tx2l.html

#6


引用 5 楼  的回复:
多线程可以构建异步模式,多线程是材料,异步模式是组织方式,把红木可以做成太师椅,但如果说太师椅比红木好,就有点不搭界。
推荐给你几篇文章吧
http://blog.csdn.net/etudiant6666/article/details/7449040

http://blog.sina.com.cn/s/blog_72ed17450100tx2l.html

请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗?

#7


当然有意义了哦

#8


引用 6 楼  的回复:
请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗

开线程吧,话说你用线程还不是要用到异步

#9


异步在多并发或者防止阻塞的时候才有意义或优势

#10


引用 6 楼  的回复:
请问如果功能上需要不停的(每间隔2秒)获取某网页的源码,然后分析对比,这样的话用线程好吗?

你的目的是发现源码不同即处理,其实是有两种思路:
1.按你想的去巡检,但它影响效率。
2. 服务器发生源码变化时,向所有激活用户发通知,客户端收到通知后进行变更。
 可见,第2种方法的效率会比较高,也可以理解为异步的另一种形式,即异步的等待并处理外部命令。

#11


对于你的代码,在异步处理时,要注意尽可能少的占用时间,即通过各个线程的信号沟通,实现事物的处理。比如你发出异步任务后,就不好使用固定的等待时间(因为这样的话,你的业务处理完了,主线程还在等待,没处理完,主线程也可能强制结束了),而最好由回调函数去释放你的阻塞等待。


namespace ConsoleApplication1
{
    class Program
    {
        public delegate string TakesAwhileDel(int data,int ms);
         ManuResetEvent _BlockEvent=new ManuResetEvent(false);

        static void Main(string[] args)
        {
            TakesAwhileDel dl = TakesAwhile;
            dl.BeginInvoke(1, 6000, AsyncCallbackImpl, dl);
             _BlockEvent.WaitOne();
             Console.ReadLine();  
        }
        public static void AsyncCallbackImpl(IAsyncResult ar)
        {
            TakesAwhileDel dl = ar.AsyncState as TakesAwhileDel;
            string re = dl.EndInvoke(ar); 
            Console.WriteLine("结果{0}", re);
            _BlockEvent.Set();
        }
        static string TakesAwhile(int data, int ms)
        {
          
            Console.WriteLine("开始调用");
            System.Threading.Thread.Sleep(ms);
            Console.WriteLine("完成调用");
            string str = "测试成功";
           
            return str;
        }  
    }
}



#12


"BeginInvoke,EndInvoke"这种模式的内部实现是使用CLR内部维护的线程池。
所以你使用这种模式省去了自己创建线程并维护等等步骤

#13


异步和多线程??这两者没有可比性吧...
我想楼主想问的是 为什么要用回调函数,不用也可以实现不是吗?
的确,不用回调函数是可以实现的,可以调用的,利用IAsyncResult对象的IsCompleted属性来判断,主线程用个while语句来控制 也就是轮循方式  就可以实现了
但是 轮询方式来检测异步方法的状态很麻烦,效率又不高
如果用回调方法的话  就改善了很多了  因为 回调方法的执行不是在主线程里执行的 而是还是在异步线程里执行的  也就不会影响主线程了

#14


关于线程池的问题  最好不要运用在长时间任务的异步处理  否则长时间占用线程池的工作线程 线程池满了以后就苦了在排队的线程了  反正自己灵活运用吧

#15


引用 12 楼  的回复:
"BeginInvoke,EndInvoke"这种模式的内部实现是使用CLR内部维护的线程池。
所以你使用这种模式省去了自己创建线程并维护等等步骤

默认线程池中的上限好像是25个

#16


默认线程池中的上限
Framework2.0中最大线程默认为25*CPU数
3.0,4.0是250*CPU数
跟cpu版本也有关系吧  
可以用ThreadPool.GetAvailableThreads( out int workerThreads,out int completionPortThreads ) 来测试下