惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
SegmentFault 最新的问题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Attack and Defense Labs
Attack and Defense Labs
F
Full Disclosure
Vercel News
Vercel News
N
News | PayPal Newsroom
The GitHub Blog
The GitHub Blog
H
Hacker News: Front Page
H
Heimdal Security Blog
P
Privacy International News Feed
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cisco Blogs
L
Lohrmann on Cybersecurity
D
Docker
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
人人都是产品经理
人人都是产品经理
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
T
Tailwind CSS Blog
C
Check Point Blog
博客园 - 叶小钗
Google Online Security Blog
Google Online Security Blog
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
S
Secure Thoughts
博客园 - Franky
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
P
Palo Alto Networks Blog
Latest news
Latest news
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
Last Week in AI
Last Week in AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
Hacker News: Ask HN
Hacker News: Ask HN
T
Threatpost
T
Tenable Blog
P
Privacy & Cybersecurity Law Blog
WordPress大学
WordPress大学

博客园 - Findekano

恩,VS调试时候的监视也不能够尽信啊 最近正在看的几本书 VS.NET2005使用体验(二) [C# FAQ]通过Windows Forms预处理Win32消息 将应用程序直接加入到"Run..."中打开的小工具 VS.NET2005使用体验(一) OpenGL & MFC 相关联接 .::Findekano's Tidbet:: .::Findekano's Tidbet:: .::Findekano's Tidbet:: .:: Findekano's Tidbet :: CorelDraw's Application Recovery Manager.. .:: Findekano's Tidbet :: C#&.NET Framework中的Beep .:: Findekano's Tidbet :: [C# FAQ]C#代码中如何启动另一个应用程序或批处理程序? 今天开始,努力攒钱... 又闻到味道 如何保持代码格式?
C#异步调用的bug?
Findekano · 2005-02-21 · via 博客园 - Findekano

C#异步调用是个好东西,省却无数麻烦。然而最近发现如果被异步调用的方法内有时间被触发,并且异步调用结束回调函数中执行序列化操作的时候就会出现结束回调函数被反复调用两次的情况。具体代码如下(从MSDN实例代码中修改而来)

using System;
using System.Threading; 
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Remoting.Messaging;

namespace test
{
    [Serializable]
    
public class AsyncDemo 
    
{
        
public delegate void TestRaiseEventHandler(object sender, EventArgs e);
        
public event TestRaiseEventHandler TestRaise;
        
protected virtual void OnTestRaiseEventHandler()
        
{
            
if (TestRaise != null)
            
{
                TestRaise(
thisnull);
            }

        }

        
// 将被异步调用的方法
        
//
        public string TestMethod(int callDuration, out int threadId) 
        
{
            Console.WriteLine(
"Test method begins.");
            OnTestRaiseEventHandler();
            Thread.Sleep(callDuration);
            threadId 
= AppDomain.GetCurrentThreadId();
            
return "MyCallTime was " + callDuration.ToString();
        }


        
// 序列化操作
        public void Serialize(string filename)
        
{
            Serialize(filename, 
this);
        }


        
public static void Serialize(string filename, AsyncDemo async) 
        

            FileStream fs 
= new FileStream(filename, FileMode.Create); 
            BinaryFormatter formatter 
= new BinaryFormatter(); 
            
try
            
{
                formatter.Serialize(fs, async);
            }

            
finally
            
{
                fs.Close(); 
            }

        }
 
    }


    
// 用来执行异步调用的代理
    public delegate string AsyncDelegate(int callDuration, out int threadId);

    
public class AsyncMain 
    
{
        
private static int threadId;

        
static void Main(string[] args) 
        
{
            
// 创建测试类
            AsyncDemo ad = new AsyncDemo();
            
// 添加事件.(1)
            ad.TestRaise += new test.AsyncDemo.TestRaiseEventHandler((new AsyncMain()).ad_TestRaise);
            
// 创建异步方法的代理
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
   
            
// 开始执行异步调用
            IAsyncResult ar = dlgt.BeginInvoke(1000,
                
out threadId, 
                
new AsyncCallback(CallbackMethod),
                ad );

            
// 等待调用完成
            Console.WriteLine("Press Enter to close application.");
            Console.ReadLine();        
        }


        
// 事件响应函数
        void ad_TestRaise(object sender, EventArgs e)
        
{
            Console.WriteLine(
"delegate call");
        }


        
// 异步调用完成时的回调函数
        static void CallbackMethod(IAsyncResult ar) 
        
{
            
// 得到异步方法的代理
            AsyncDelegate dlgt = (AsyncDelegate) (ar as AsyncResult).AsyncDelegate;        
            Console.WriteLine(
"begin EndInvoke");
            
string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine(
"The call executed on thread {0}, with return value \"{1}\".", threadId, ret);

            
// 执行序列化操作(2)
            AsyncDemo demo = ar.AsyncState as AsyncDemo;
            demo.Serialize(
"Test.dat");
        }

    }

}


上述代码输出如下:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Press Enter to close application.
Test method begins.
delegate call
begin EndInvoke
The call executed on thread 3736, with return value "MyCallTime was 1000".
begin EndInvoke
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
如上代码可见,当同时具备两个条件时:
(1)异步方法中有事件发生并被客户代码响应,
(2)异步操作结束时执行序列化操作
CallbackMethod方法将被执行两次,且序列化操作不能正常完成,第二次执行的时候终止于EndInvoke语句。
在网络上查询似乎并没有关于这个问题的描述,不知道是否有人遇到过相似的问题?