সত্তা ফ্রেমওয়ার্ক async অপারেশন সম্পূর্ণ হতে দশ গুণ সময় নেয়


139

আমি একটি এমভিসি সাইট পেয়েছি যা ডেটাবেস হ্যান্ডেল করার জন্য সত্তা ফ্রেমওয়ার্ক 6 ব্যবহার করছে এবং আমি এটি পরিবর্তন করার জন্য পরীক্ষা-নিরীক্ষা করে যাচ্ছি যাতে সমস্ত কিছু অ্যাসিঙ্ক নিয়ন্ত্রণকারী হিসাবে চালিত হয় এবং ডাটাবেসে কলগুলি তাদের অ্যাসিঙ্ক প্রতিযোগী হিসাবে চালিত হয় (যেমন। টোলিস্টএন্সিঙ্ক () ToList () এর পরিবর্তে

আমার যে সমস্যা হচ্ছে তা হ'ল আমার প্রশ্নগুলিকে কেবল অ্যাসিঙ্কে পরিবর্তন করার ফলে এগুলি অবিশ্বাস্যরকম ধীর হয়ে গেছে।

নিম্নলিখিত কোডটি আমার ডেটা প্রসঙ্গ থেকে "অ্যালবাম" অবজেক্টের সংকলন পায় এবং মোটামুটি সহজ ডাটাবেসে যোগদানের জন্য অনুবাদ হয়:

// Get the albums
var albums = await this.context.Albums
    .Where(x => x.Artist.ID == artist.ID)
    .ToListAsync();

এটি যে এসকিউএল তৈরি করেছে তা এখানে:

exec sp_executesql N'SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[URL] AS [URL], 
[Extent1].[ASIN] AS [ASIN], 
[Extent1].[Title] AS [Title], 
[Extent1].[ReleaseDate] AS [ReleaseDate], 
[Extent1].[AccurateDay] AS [AccurateDay], 
[Extent1].[AccurateMonth] AS [AccurateMonth], 
[Extent1].[Type] AS [Type], 
[Extent1].[Tracks] AS [Tracks], 
[Extent1].[MainCredits] AS [MainCredits], 
[Extent1].[SupportingCredits] AS [SupportingCredits], 
[Extent1].[Description] AS [Description], 
[Extent1].[Image] AS [Image], 
[Extent1].[HasImage] AS [HasImage], 
[Extent1].[Created] AS [Created], 
[Extent1].[Artist_ID] AS [Artist_ID]
FROM [dbo].[Albums] AS [Extent1]
WHERE [Extent1].[Artist_ID] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=134

জিনিসগুলি যেতে গেলে এটি কোনও জটিল জটিল অনুসন্ধান নয়, তবে এসকিউএল সার্ভারটি চালাতে প্রায় 6 সেকেন্ড সময় লাগবে। এসকিউএল সার্ভার প্রোফাইলার এটি সম্পূর্ণরূপে 5742ms গ্রহণ হিসাবে রিপোর্ট করেছে।

আমি যদি আমার কোডটি এতে পরিবর্তন করি:

// Get the albums
var albums = this.context.Albums
    .Where(x => x.Artist.ID == artist.ID)
    .ToList();

তারপরে ঠিক একই এসকিউএল উত্পন্ন হয়, তবু এটি এসকিউএল সার্ভার প্রোফাইলার অনুসারে মাত্র 474 মিমিগুলিতে চলে।

"অ্যালবাম" টেবিলটিতে ডাটাবেসটির প্রায় 3500 টি সারি রয়েছে, যা আসলে খুব বেশি নয় এবং "আর্টিস্ট_আইডি" কলামে একটি সূচক রয়েছে, সুতরাং এটি খুব দ্রুত হওয়া উচিত।

আমি জানি যে অ্যাসিঙ্কের ওভারহেড রয়েছে তবে জিনিসগুলি দশগুণ কমিয়ে দেওয়া আমার কাছে কিছুটা খাড়া মনে হয়! আমি এখানে কোথায় ভুল করছি?


এটি আমার কাছে ঠিক দেখাচ্ছে না। আপনি যদি একই ডেটা দিয়ে একই ক্যোয়ারী চালিত করেন, এসকিউএল সার্ভার প্রোফাইলার দ্বারা রিপোর্ট করা সম্পাদনের সময়টি কম বেশি একই হওয়া উচিত কারণ এসাইক্যেলটি সি # তে ঘটেছিল, এসকিএল-তে নয়। এসকিএল সার্ভারটি আপনার সচেতন নয় যে আপনার সি # কোডটি অ্যাসিঙ্ক
খান

আপনি যখন প্রথম উত্পন্ন উত্সাহিত ক্যোয়ারী চালান, দ্বিতীয় বার থেকে একই ক্যোয়ারীটি দ্রুত হতে পারে (এসকিউএল সার্ভারটি ক্যোয়ারীটিকে ক্যাশে করে), কোয়েরিটি সংকলন করতে কিছুটা বেশি সময় নিতে পারে (এসকিএল সার্ভারটি ক্যোয়ারী ক্যাশে করে) তবে খুব বেশি আলাদা হওয়া উচিত নয়।
খানহ টু

3
আপনার ধীর গতির তা নির্ধারণ করা দরকার। অসীম লুপে ক্যোয়ারী চালান। ডিবাগারটি 10 ​​বার বিরতি দিন। এটি প্রায়শই কোথায় থামে? বহিরাগত কোড সহ স্ট্যাক পোস্ট করুন।
usr

1
দেখে মনে হচ্ছে সমস্যাটি ইমেজ সম্পত্তিটির সাথে করা, যা আমি সম্পূর্ণরূপে ভুলে গিয়েছিলাম। এটি একটি ভারবাইনারি (ম্যাক্স) কলাম, সুতরাং মন্দার কারণ হতে বাধ্য, তবে এটি এখনও খানিকটা অদ্ভুত যে স্লোনেস কেবল অ্যাসিঙ্ক চলমান একটি সমস্যা হয়ে দাঁড়িয়েছে। আমি আমার ডাটাবেসটিকে পুনর্গঠন করেছি যাতে চিত্রগুলি এখন কোনও লিঙ্কযুক্ত টেবিলের অংশ এবং সবকিছু এখন অনেক দ্রুত।
ডিলান প্যারি

1
সমস্যাটি হতে পারে যে EF all সমস্ত বাইট এবং সারিগুলি পুনরুদ্ধার করতে ADO.NET- র কাছে প্রচুর অ্যাসিঙ্ক সরবরাহ করছে nc এইভাবে ওভারহেড বিস্তৃত হয়। যেহেতু আপনি যে পরিমাপটি করেছিলেন আমি তা সম্পাদন না করেছিলাম আমরা কখনই জানতে পারি না। সমস্যার সমাধান হচ্ছে বলে মনে হচ্ছে।
usr

উত্তর:


286

আমি এই প্রশ্নটি খুব আকর্ষণীয় পেয়েছি, বিশেষত যেহেতু আমি asyncএডো.নেট এবং ইএফ with এর সাথে সর্বত্র ব্যবহার করছি আমি আশা করি যে কেউ এই প্রশ্নের ব্যাখ্যা দেবে বলে আশাবাদী, তবে তা ঘটেনি। তাই আমি আমার পক্ষ থেকে এই সমস্যাটি পুনরুত্পাদন করার চেষ্টা করেছি। আমি আশা করি আপনারা কেউ কেউ এটি আকর্ষণীয় দেখতে পাবেন।

প্রথম সুসংবাদ: আমি এটি পুনরুত্পাদন করেছি :) এবং পার্থক্যটি বিশাল। 8 একটি ফ্যাক্টর সহ ...

প্রথম ফলাফল

প্রথমে আমি সঙ্গে তার আচরণ কিছু ধারণা ছিল CommandBehaviorযেহেতু, আমি একটি আকর্ষণীয় নিবন্ধ পড়া সম্পর্কে asyncAdo সঙ্গে এই বলছে:

"যেহেতু অ-অনুক্রমিক অ্যাক্সেস মোডটিকে পুরো সারির জন্য ডেটা সংরক্ষণ করতে হয়, তাই আপনি যদি সার্ভার থেকে বৃহত্তর কলামটি পড়ছেন (যেমন ভের্বাইনারি (ম্যাক্স), বার্চর (ম্যাক্স), এনভারচার (ম্যাক্স) বা এক্সএমএল )। "

আমি ToList()কলগুলি CommandBehavior.SequentialAccessএবং অ্যাসিঙ্ক হওয়ার কথা সন্দেহ করছিলাম CommandBehavior.Default(অ-অনুক্রমিক, যা সমস্যার কারণ হতে পারে)। সুতরাং আমি EF6 এর উত্স ডাউনলোড করেছি এবং সর্বত্র ব্রেকপয়েন্টগুলি রেখেছি (যেখানে CommandBehaviorযেখানে ব্যবহৃত হয় অবশ্যই)।

ফলাফল: কিছুই না । সমস্ত কলগুলি দিয়ে করা হয়েছে CommandBehavior.Default.... সুতরাং আমি কী ঘটেছিল তা বোঝার জন্য EF কোডের মধ্যে পদক্ষেপের চেষ্টা করেছি ... এবং .. আউচ ... আমি কখনই এই জাতীয় প্রতিনিধি কোড দেখি না, সবকিছু অলস বলে মনে হচ্ছে ...

তাই আমি কী হয় তা বুঝতে কিছু প্রোফাইল করার চেষ্টা করেছি ...

এবং আমার মনে হয় আমার কিছু আছে ...

এখানে 3500 টি লাইন এবং প্রতিটিতে 256 কেবি এলোমেলো ডেটা সহ আমি বেঞ্চমার্কযুক্ত সারণী তৈরি করার মডেল এখানে varbinary(MAX)। (মতিন 6.1 - CodeFirst - CodePlex ):

public class TestContext : DbContext
{
    public TestContext()
        : base(@"Server=(localdb)\\v11.0;Integrated Security=true;Initial Catalog=BENCH") // Local instance
    {
    }
    public DbSet<TestItem> Items { get; set; }
}

public class TestItem
{
    public int ID { get; set; }
    public string Name { get; set; }
    public byte[] BinaryData { get; set; }
}

এবং আমি টেস্ট ডেটা তৈরি করতে কোডটি ব্যবহার করেছি এবং বেঞ্চমার্ক EF।

using (TestContext db = new TestContext())
{
    if (!db.Items.Any())
    {
        foreach (int i in Enumerable.Range(0, 3500)) // Fill 3500 lines
        {
            byte[] dummyData = new byte[1 << 18];  // with 256 Kbyte
            new Random().NextBytes(dummyData);
            db.Items.Add(new TestItem() { Name = i.ToString(), BinaryData = dummyData });
        }
        await db.SaveChangesAsync();
    }
}

using (TestContext db = new TestContext())  // EF Warm Up
{
    var warmItUp = db.Items.FirstOrDefault();
    warmItUp = await db.Items.FirstOrDefaultAsync();
}

Stopwatch watch = new Stopwatch();
using (TestContext db = new TestContext())
{
    watch.Start();
    var testRegular = db.Items.ToList();
    watch.Stop();
    Console.WriteLine("non async : " + watch.ElapsedMilliseconds);
}

using (TestContext db = new TestContext())
{
    watch.Restart();
    var testAsync = await db.Items.ToListAsync();
    watch.Stop();
    Console.WriteLine("async : " + watch.ElapsedMilliseconds);
}

using (var connection = new SqlConnection(CS))
{
    await connection.OpenAsync();
    using (var cmd = new SqlCommand("SELECT ID, Name, BinaryData FROM dbo.TestItems", connection))
    {
        watch.Restart();
        List<TestItem> itemsWithAdo = new List<TestItem>();
        var reader = await cmd.ExecuteReaderAsync(CommandBehavior.SequentialAccess);
        while (await reader.ReadAsync())
        {
            var item = new TestItem();
            item.ID = (int)reader[0];
            item.Name = (String)reader[1];
            item.BinaryData = (byte[])reader[2];
            itemsWithAdo.Add(item);
        }
        watch.Stop();
        Console.WriteLine("ExecuteReaderAsync SequentialAccess : " + watch.ElapsedMilliseconds);
    }
}

using (var connection = new SqlConnection(CS))
{
    await connection.OpenAsync();
    using (var cmd = new SqlCommand("SELECT ID, Name, BinaryData FROM dbo.TestItems", connection))
    {
        watch.Restart();
        List<TestItem> itemsWithAdo = new List<TestItem>();
        var reader = await cmd.ExecuteReaderAsync(CommandBehavior.Default);
        while (await reader.ReadAsync())
        {
            var item = new TestItem();
            item.ID = (int)reader[0];
            item.Name = (String)reader[1];
            item.BinaryData = (byte[])reader[2];
            itemsWithAdo.Add(item);
        }
        watch.Stop();
        Console.WriteLine("ExecuteReaderAsync Default : " + watch.ElapsedMilliseconds);
    }
}

using (var connection = new SqlConnection(CS))
{
    await connection.OpenAsync();
    using (var cmd = new SqlCommand("SELECT ID, Name, BinaryData FROM dbo.TestItems", connection))
    {
        watch.Restart();
        List<TestItem> itemsWithAdo = new List<TestItem>();
        var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
        while (reader.Read())
        {
            var item = new TestItem();
            item.ID = (int)reader[0];
            item.Name = (String)reader[1];
            item.BinaryData = (byte[])reader[2];
            itemsWithAdo.Add(item);
        }
        watch.Stop();
        Console.WriteLine("ExecuteReader SequentialAccess : " + watch.ElapsedMilliseconds);
    }
}

using (var connection = new SqlConnection(CS))
{
    await connection.OpenAsync();
    using (var cmd = new SqlCommand("SELECT ID, Name, BinaryData FROM dbo.TestItems", connection))
    {
        watch.Restart();
        List<TestItem> itemsWithAdo = new List<TestItem>();
        var reader = cmd.ExecuteReader(CommandBehavior.Default);
        while (reader.Read())
        {
            var item = new TestItem();
            item.ID = (int)reader[0];
            item.Name = (String)reader[1];
            item.BinaryData = (byte[])reader[2];
            itemsWithAdo.Add(item);
        }
        watch.Stop();
        Console.WriteLine("ExecuteReader Default : " + watch.ElapsedMilliseconds);
    }
}

নিয়মিত ইএফ কল ( .ToList()) এর জন্য, প্রোফাইলিংটি "সাধারণ" বলে মনে হচ্ছে এবং এটি পড়া সহজ:

টোললিস্ট ট্রেস

এখানে আমরা স্টপওয়াচটি দিয়ে আমাদের 8.4 সেকেন্ড পেয়েছি (প্রোফাইলিং ধীরে ধীরে পারফটি নিচে নামায়)। আমরা কল পথের সাথে হিটকাউন্ট = 3500ও পাই, যা পরীক্ষার 3500 লাইনের সাথে সামঞ্জস্যপূর্ণ। টিডিএস পার্সার সাইডে, TryReadByteArray()পদ্ধতিগুলিতে 118 353 টি কল পড়ার পরে জিনিসগুলি আরও খারাপ হতে শুরু করে , যা ছিল বার্ফিং লুপটি। ( byte[]256kb প্রত্যেকের জন্য গড়ে 33.8 টি কল )

কেসটির জন্য async, এটি সত্যিই অন্যরকম .... প্রথমে .ToListAsync()কলটি থ্রেডপুলে নির্ধারিত হয়েছে এবং তারপরে অপেক্ষা করা হচ্ছে। এখানে আশ্চর্যজনক কিছুই। তবে, এখন asyncথ্রেডপুলের নরকটি এখানে:

ToListAsync নরক

প্রথমত, প্রথম ক্ষেত্রে আমরা পুরো কল পাথ ধরে কেবল 3500 হিট সংখ্যা পেয়েছিলাম, এখানে আমাদের 118 371 রয়েছে Moreover তদুপরি, আপনি স্ক্রিনশুটটি না রেখে সমস্ত সিঙ্ক্রোনাইজেশন কলগুলি কল্পনা করতে হবে ...

দ্বিতীয়ত, প্রথম ক্ষেত্রে, আমাদের TryReadByteArray()পদ্ধতিটিতে "মাত্র 118 353" কল ছিল , এখানে আমাদের কাছে 050 210 কল রয়েছে! এটি 17 গুণ বেশি ... (বৃহত 1 এমবি অ্যারের সাথে পরীক্ষায় এটি 160 গুণ বেশি)

তাছাড়া এখানে রয়েছে:

  • 120 000 Taskদৃষ্টান্ত তৈরি করা হয়েছে
  • 727 519 Interlockedকল
  • 290 569 Monitorকল
  • ExecutionContext264 481 ক্যাপচার সহ 98 283 টি উদাহরণ
  • 208 733 SpinLockকল

আমার ধারণা, বাফারিং টিএসডি থেকে ডেটা পড়ার চেষ্টা করে সমান্তরাল টাস্ক সহ একটি অ্যাসিঙ্ক উপায়ে তৈরি করা হয়েছে (এবং ভাল নয়)। কেবল বাইনারি ডেটা পার্স করার জন্য অনেকগুলি টাস্ক তৈরি করা হয়েছে।

প্রাথমিক উপসংহার হিসাবে আমরা বলতে পারি Async দুর্দান্ত, EF6 দুর্দান্ত, তবে EF6 এর বর্তমান বাস্তবায়নে async ব্যবহারের ফলে পারফরম্যান্সের দিক, থ্রেডিং সাইড এবং সিপিইউ পাশ (12% সিপিইউ ব্যবহার) 8 থেকে 10 গুণ বেশি দীর্ঘ কাজের জন্য ToList()কেস এবং 20% ToListAsyncক্ষেত্রে ... আমি এটি একটি পুরানো আই 7920 তে চালাই)।

কিছু পরীক্ষা করার সময়, আমি আবার এই নিবন্ধটি সম্পর্কে ভাবছিলাম এবং আমি কিছু মিস করেছি তা লক্ষ্য করি:

"নেট .৪.৫-এ নতুন অ্যাসিনক্রোনাস পদ্ধতির জন্য, তাদের আচরণ হ'ল সিঙ্ক্রোনাস পদ্ধতিগুলির সাথে হ'ল এক উল্লেখযোগ্য ব্যতিক্রম ব্যতীত: নন-সিক্যুয়াল মোডে রিডএেন্সিক।"

কি ?!!!

তাই আমি নিয়মিত / অ্যাসিঙ্ক কল এবং CommandBehavior.SequentialAccess/ এর সাথে অ্যাডো.নেট অন্তর্ভুক্ত করার জন্য আমার মানদণ্ডগুলি প্রসারিত করি CommandBehavior.Defaultএবং এখানে একটি বিস্ময়! :

অ্যাডো সহ

অ্যাডো.নেটের সাথে আমাদের ঠিক একই আচরণ রয়েছে !!! Facepalm ...

আমার চূড়ান্ত উপসংহারটি হল : EF 6 বাস্তবায়নে একটি বাগ আছে। এটা তোলে টগল উচিত CommandBehaviorকরার SequentialAccessএকটি ASYNC কলের জন্য একটি সমন্বিত একটি টেবিলের উপর তৈরি করা হয় যখন binary(max)কলাম। প্রক্রিয়াটি ধীরগতিতে অনেক বেশি টাস্ক তৈরির সমস্যাটি অ্যাডো.নেট দিকে রয়েছে। EF সমস্যাটি হ'ল এটি অ্যাডো.নেটকে যেমন ব্যবহার করা উচিত তেমন ব্যবহার করে না।

এখন আপনি জানেন যে EF6 অ্যাসিঙ্ক পদ্ধতিগুলি ব্যবহার করার পরিবর্তে আপনাকে নিয়মিত অ-অ্যাসিঙ্ক পদ্ধতিতে EF কল করতে হবে, এবং তারপরে TaskCompletionSource<T>ফলাফলটি অ্যাসিঙ্ক পদ্ধতিতে ফেরত দিতে একটি ব্যবহার করতে হবে।

নোট 1: লজ্জাজনক ত্রুটির কারণে আমি আমার পোস্টটি সম্পাদনা করেছি .... আমি স্থানীয়ভাবে নয়, নেটওয়ার্কের মাধ্যমে আমার প্রথম পরীক্ষাটি করেছি এবং সীমিত ব্যান্ডউইথ ফলাফলগুলি বিকৃত করেছে। এখানে আপডেট ফলাফল।

দ্রষ্টব্য 2: আমি অন্য পরীক্ষার ক্ষেত্রে আমার পরীক্ষাটি প্রসারিত করি নি (উদাহরণস্বরূপ: nvarchar(max)প্রচুর ডেটা সহ) তবে একই আচরণ হওয়ার সম্ভাবনা রয়েছে।

দ্রষ্টব্য 3: ToList()মামলার জন্য সাধারণ কিছু , 12% সিপিইউ (আমার সিপিইউ = 1 লজিক্যাল কোরের 1/8)। কিছু অস্বাভাবিক কিছু হ'ল ToListAsync()মামলার সর্বোচ্চ 20% , কারণ শিডিয়ুলার সমস্ত ট্র্যাড ব্যবহার করতে না পারলে। এটি সম্ভবত অনেকগুলি টাস্ক তৈরি হওয়ার কারণে, বা টিডিএস পার্সারে কোনও বাধা থাকতে পারে, আমি জানি না ...


2
আমি কোডেপ্লেক্সে একটি ইস্যু খুললাম, আশা করি তারা এ বিষয়ে কিছু করবেন। অ্যান্টিফ্রেমওয়ার্ক.কোডপ্লেক্স
ওয়ার্কেম /


5
দুঃখের সাথে গিটারহাবের সমস্যাটি ভের্বাইনারি সহ অ্যাসিঙ্ক ব্যবহার না করার পরামর্শ দিয়ে বন্ধ করা হয়েছে। তত্ত্বের ক্ষেত্রে ভেরিবিনারিটি এমন ক্ষেত্রে হওয়া উচিত যেখানে অ্যাসিঙ্কটি সর্বাধিক অর্থবোধ করে কারণ ফাইলটি সংক্রমণ করার সময় থ্রেডটি দীর্ঘায়িত হবে। সুতরাং এখন আমরা ডিবিতে বাইনারি ডেটা সংরক্ষণ করতে চাইলে আমরা কী করব?
স্টিলগার

8
কেউ কি জানেন যে এটি এখনও ইএফ কোর-এর কোনও সমস্যা? আমি কোনও তথ্য বা মানদণ্ড খুঁজে পেতে অক্ষম হয়েছি।
অ্যান্ড্রু লুইস

2
@ অ্যান্ড্রুলিউইস এর পিছনে আমার কোন বিজ্ঞান নেই, তবে ইএফ কোরের সাথে আমার বারবার সংযোগ পুলের সময়সীমা বেঁধে দেওয়া হচ্ছে যেখানে দু'টি সমস্যা দেখা দিচ্ছে .ToListAsync()এবং .CountAsync()... অন্য কারও কাছে এই মন্তব্য থ্রেডটি খুঁজে পাওয়া গেলে এই জিজ্ঞাসাটি সাহায্য করতে পারে। Godspeed।
স্কট

2

কারণ আমি এই প্রশ্নের একটি লিঙ্ক পেয়েছি কয়েক দিন আগে আমি একটি ছোট আপডেট পোস্ট করার সিদ্ধান্ত নিয়েছি। আমি বর্তমানে, ইএফ (6.4.0) এর সর্বশেষতম সংস্করণ এবং। নেট ফ্রেমওয়ার্ক 4.7.2 ব্যবহার করে মূল উত্তরের ফলাফলগুলি পুনরায় উত্পাদন করতে সক্ষম হয়েছি। আশ্চর্যজনকভাবে এই সমস্যাটি কখনই উন্নত হয়নি।

.NET Framework 4.7.2 | EF 6.4.0 (Values in ms. Average of 10 runs)

non async : 3016
async : 20415
ExecuteReaderAsync SequentialAccess : 2780
ExecuteReaderAsync Default : 21061
ExecuteReader SequentialAccess : 3467
ExecuteReader Default : 3074

এই প্রশ্নটি জিজ্ঞাসা: ডটনেট কোর উন্নতি আছে?

আমি কোডটি মূল উত্তর থেকে একটি নতুন ডটনেট কোর 3.1.3 প্রকল্পে অনুলিপি করেছি এবং EF কোর 3.1.3 যুক্ত করেছি। ফলাফলগুলি হ'ল:

dotnet core 3.1.3 | EF Core 3.1.3 (Values in ms. Average of 10 runs)

non async : 2780
async : 6563
ExecuteReaderAsync SequentialAccess : 2593
ExecuteReaderAsync Default : 6679
ExecuteReader SequentialAccess : 2668
ExecuteReader Default : 2315

আশ্চর্যজনকভাবে অনেক উন্নতি হয়েছে। থ্রেডপুল কল হয়ে যায় বলে এখনও কিছুটা সময় পিছনে রয়েছে বলে মনে হচ্ছে তবে এটি নেট ফ্রেমওয়ার্ক বাস্তবায়নের চেয়ে প্রায় 3 গুণ বেশি দ্রুত।

আমি আশা করি এই উত্তর ভবিষ্যতে এইভাবে প্রেরণ করা অন্যান্য লোকদের সহায়তা করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.