এক্সএমএলসিরালাইজার কনস্ট্রাক্টরে ফাইলনটফাউন্ডএক্সপশন দিচ্ছেন


347

আমি যখন অ্যাপ্লিকেশনগুলির সাথে কাজ করেছিলাম ব্যর্থ হয় যখন আমি ধরণের সিরিয়ালাইজ করার চেষ্টা করি।

মত একটি বিবৃতি

XmlSerializer lizer = new XmlSerializer(typeof(MyType));

সৃষ্টি করে:

System.IO.FileNotFoundException occurred
  Message="Could not load file or assembly '[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
  Source="mscorlib"
  FileName="[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
  FusionLog=""
  StackTrace:
       at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
       at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)

আমি আমার ক্লাসের জন্য কোনও বিশেষ সিরিয়ালাইজার সংজ্ঞায়িত করি না।

আমি কিভাবে এই সমস্যা ঠিক করতে পারবো?


5
ঠিক আছে, সুতরাং এই প্রশ্নটি আমার ইতিমধ্যে জিজ্ঞাসিত ভিবি প্রশ্নের কেবলমাত্র # সি সংস্করণ: স্ট্যাকওভারফ্লো / প্রশ্ন / 294659/… ধন্যবাদ ছেলেরা।
ইরভিন

1
ছয় বছর পরে, @ ভ্ল্যাডভির উত্তর হ'ল সহজ এবং সর্বনিম্ন বিরূপ-প্রভাবিত সমাধান। শুধু পরিবর্তন Generate serialization assembly"অটো" এর পরিবর্তে, "অন" এ ড্রপ ডাউন।
হেলিয়াক

@ হেলিয়াক: আমি একমত নই এটি সবসময় কাজ করে না। ভ্লাদ এর উত্তরে বেনোইট ব্লাঞ্চনের মন্তব্য দেখুন। আমার পক্ষে সহজ উত্তরটি হচ্ছে কনফিগার ফাইলগুলিতে স্ট্রিং.কলেশন ব্যবহার না করা। পরিবর্তে আমি ব্যবহার করি: স্ট্রিং [] আইটেমগুলি = সেটিংস.ডাফল্ট.স্ট্রিংফ নিউইলাইনলাইমিটাইটস.স্প্লিট (নতুন [] {পরিবেশনা.নউলাইন});
অ্যান্ড্রু ডেনিসন

উত্তর:


388

বিশ্বাস করুন বা না করুন, এটি স্বাভাবিক আচরণ। এক্সএমএসআরশায়ালাইজার একটি ব্যতিক্রম নিক্ষেপ করে তবে পরিচালনা করে, তাই আপনি যদি এটিকে এড়িয়ে যান তবে সবকিছু ঠিকঠাক করা উচিত।

আমি এটি খুব বিরক্তিকর পেয়েছি এবং আপনি যদি কিছুটা অনুসন্ধান করেন তবে এ সম্পর্কে অনেক অভিযোগ রয়েছে, তবে যা আমি মাইক্রোসফ্ট পড়েছি সেগুলি সম্পর্কে কিছুই করার পরিকল্পনা করে না।

আপনি যদি সুনির্দিষ্ট ব্যতিক্রমের জন্য প্রথম সুযোগ ব্যতিক্রমগুলি স্যুইচ করেন তবে ডিবাগ করার সময় আপনি সর্বদা ব্যতিক্রম পপআপগুলি এড়াতে পারবেন। ভিজ্যুয়াল স্টুডিওতে, ডিবাগ -> ব্যতিক্রমগুলি (বা Ctrl+ Alt+ টিপুন E), কমন ল্যাঙ্গুয়েজ রানটাইম ব্যতিক্রম -> সিস্টেম.আইও -> সিস্টেম.আইও.ফাইলনটফাউন্ড এক্সপ্লেশন এ যান

ব্লগ পোস্ট সি # এক্সএমএলসিরিয়ালাইজার ফাইলনটফাউন্ড ব্যতিক্রম (যা ক্রিস সেলসের সরঞ্জাম XMLSerializerPreCompiler আলোচনা করে ) এর আশেপাশে অন্য উপায় সম্পর্কে আপনি তথ্য পেতে পারেন ।


162
এই সমস্যা থেকে মুক্তি পাওয়ার একটি সম্ভাব্য উপায় হ'ল সরঞ্জামসমূহ -> বিকল্পগুলি -> ডিবাগিং -> সাধারণ বিকল্পগুলির মধ্যে "জাস্ট মাই কোড" বিকল্পটি চেক করুন।
ফ্রেডেরিক

26
@ ফ্রেডেরিক: এই মন্তব্যটি দুর্দান্ত! আমি এখানে "WTF !?" নিয়ে বসে আছি আমার মুখের অভিব্যক্তি, এই উত্সাহী ব্যতিক্রমটি নীচে শিকার করার চেষ্টা করছি এবং আমি এই প্রশ্নের উত্তর পেয়েছি (এটি মাইক্রোসফ্টের দোষ, আর কী নতুন?), তবে আমি ব্যতিক্রম হ্যান্ডলিংটি অক্ষম করতে চাইনি, কারণ আমার এটির প্রয়োজন হতে পারে আমার কোড প্রথম সারির!
কুম্বা

27
আমি মনে করি নীচে হ্যান্সের পরামর্শটি আরও মূল্যবান - একটি ভিন্ন পদ্ধতি কল ব্যবহার করুন যা এই ব্যতিক্রমটি মোটেও উত্পাদন করে না: এক্সএমএসআরসিরিয়াল সিরিয়ালাইজার = এক্সএমএলসিরাইজার। ফর্মটাইপস (নতুন [] {টাইপফ (মাইটাইপ)}) [0];
উজ্জ্বল

3
সমস্যাটি হ'ল এটি আমার পরীক্ষায় ব্যর্থ হয়, সুতরাং আমি কেবল ব্যতিক্রমটিকে "উপেক্ষা" করতে পারি না
সিএসবা তোথ

16
আমি দুঃখিত, তবে এটি একটি ভয়ানক পরামর্শ। আমার অভিজ্ঞতার মধ্যে ফাইলনটফাউন্ডএক্সেপশন অন্যতম সাধারণ বিষয়, এবং এই ব্যতিক্রম প্রতিবেদনটি অক্ষম করা ভবিষ্যতে কোনও দিন কেবল ঝামেলা চাইছে। 'জাস্ট মাই কোড' চালু করা বা নীচে বর্ণিত সিরিয়ালাইজেশন অ্যাসেম্বলিগুলি তৈরি করা সক্ষম করা ভাল।
Quarkly

104

মার্টিন শেরবার্ন যেমন বলেছেন, এটি স্বাভাবিক আচরণ। এক্সএমএসআরশায়ালাইজারের কনস্ট্রাক্টর প্রথমে [আপনারআসপ্লেপস] .XMLSerializer.dll নামে একটি অ্যাসেমব্লী সন্ধান করার চেষ্টা করে যা আপনার ধরণের সিরিয়ালাইজেশনের জন্য উত্পন্ন শ্রেণি থাকা উচিত। যেহেতু এ জাতীয় ডিএলএল এখনও তৈরি করা হয়নি (সেগুলি ডিফল্টরূপে হয় না), তাই কোনও ফাইলনটফাউন্ডএক্সসেপশন নিক্ষেপ করা হয়। যখন এটি ঘটে থাকে, এক্সএমএসরিশিলাইজারের কনস্ট্রাক্টর সেই ব্যতিক্রমটি ধরেন এবং এক্সএমএসরিশালাইজারের কনস্ট্রাক্টর দ্বারা রানটাইম সময়ে ডিএলএল স্বয়ংক্রিয়ভাবে উত্পন্ন হয় (এটি আপনার কম্পিউটারের% টেম্প%% ডিরেক্টরিতে সি # উত্স ফাইলগুলি তৈরি করে সি সি সংকলক ব্যবহার করে সংকলন করে) comp একই ধরণের জন্য একটি এক্সএমএলসিরিয়ালাইজারের অতিরিক্ত নির্মাণগুলি কেবল ইতিমধ্যে উত্পাদিত ডিএলএল ব্যবহার করবে।

আপডেট: .NET 4.5 থেকে শুরু করে, XmlSerializerআর কোড টাইম জেনারেশন সম্পাদন করে না বা রানটাইমের সময় সিরিয়ালাইজার অ্যাসেমব্লি তৈরির জন্য সি # সংকলকটির সাথে সংকলন সম্পাদন করে না, যদি না কোনও কনফিগারেশন ফাইল সেটিংস ( useLegacySerializerGeneration ) সেট করে স্পষ্টভাবে বাধ্য করা হয় । এই পরিবর্তনটির উপর নির্ভরতা সরিয়ে দেয় csc.exeএবং প্রারম্ভকৃত পারফরম্যান্সকে উন্নত করে। উত্স:। নেট ফ্রেমওয়ার্ক 4.5 রেডমি , বিভাগ 1.3.8.1।

ব্যতিক্রমটি এক্সএমএলসিরিয়ালাইজারের কনস্ট্রাক্টর দ্বারা পরিচালিত। নিজেকে কিছু করার দরকার নেই, আপনি নিজের প্রোগ্রামটি চালিয়ে যেতে চালিয়ে যেতে 'চালিয়ে যান' (এফ 5) এ ক্লিক করতে পারেন এবং সবকিছু ঠিকঠাক হয়ে যাবে। যদি আপনি ব্যতিক্রমগুলি দ্বারা আপনার প্রোগ্রামটির সম্পাদন বন্ধ করে এবং কোনও ব্যতিক্রম সহায়ককে পপ করে বিরক্ত হয়ে থাকেন তবে আপনি হয় 'জাস্ট মাই কোড' বন্ধ করে দিয়েছেন, অথবা আপনি যখন ফাইল-নটফাউন্ডএক্সেপশন নিক্ষেপ করার সময় নির্ধারিত বিরতিতে সেট করেছেন তখন 'ইউজার- অপরিচালিত '।

'জাস্ট মাই কোড' সক্ষম করতে, সরঞ্জামসমূহ >> বিকল্পসমূহ >> ডিবাগিং >> সাধারণ >> কেবল আমার কোড সক্ষম করুন to ফাইলনটফাউন্ড নিক্ষেপ করা হলে মৃত্যুদন্ড কার্যকর করা বন্ধ করতে, ডিবাগ >> ব্যতিক্রম >> সন্ধান করুন >> 'ফাইলনটফাউন্ডএক্সেপশন' সন্নিবেশ করুন >> সিস্টেম.আইও.ফিলনটফাউন্ডএক্সেপশন থেকে 'থ্রাউন' চেকবাক্সটি আনটিক করুন।


আপডেটের জন্য +1: পরীক্ষার কেসগুলি ডিবাগ করার সময় এটি বিভিন্ন আচরণের ব্যাখ্যা করে
এমবিএক্স

3
আপনার আপডেটটি পরামর্শ দেয় যে এই ব্যতিক্রমটি .NET 4.5 এ না হওয়া উচিত, তবে আমি এটি এখনও দেখছি।
টিম্বো

@ টিমবো: আপনি। নেট 4.5 এর সাথে কেন এই ব্যতিক্রমটি পাবেন না তা আমি দেখতে পাচ্ছি না। এটি এখনও একটি ফাইল সন্ধান করে এবং যদি ফাইলটি অনুপস্থিত থাকে তবে একটি FileNotFoundExceptionনিক্ষেপ করা হবে। পার্থক্যটি কীভাবে সমাবেশের অস্তিত্ব পরীক্ষা করা হয় তা নয়, তবে এটি নির্ধারণ করা হয়েছে যে একবার এটি কীভাবে তৈরি করা যায়। এর আগে, এটি আইএল তৈরির জন্য সি # সংকলককে কল দিয়ে পাঠ্য সি # কোড জেনারেশন ব্যবহার করেছিল। .NET 4.5 দিয়ে শুরু করে এটি কোনও সংকলক ব্যবহার না করে সরাসরি আইএলকে নির্গত করে।
অ্যালন গুরালেক

1
আমি কেবল চাই এমএস এটি প্রয়োগ করে যেন (ফাইল.এক্সজিস্ট (...)) {লোড} অন্যথায় all ফলব্যাক try পরিবর্তে {লোড} ক্যাচ {ফলব্যাক try চেষ্টা করুন} ব্যতিক্রম-ভিত্তিক প্রবাহ নিয়ন্ত্রণের দুর্গন্ধযুক্ত এবং আমার ডিবাগিংয়ের অভিজ্ঞতাকে প্রয়োজনের চেয়ে আরও বেশি কঠিন এবং ভঙ্গুর করে তোলে।
টিম্বো

1
@ টিম্বো: একটি সরল File.Exists()যথেষ্ট নাও হতে পারে। অ্যাসেমবিলি সন্ধান করা কোনও সহজ ব্যাপার নয়, রানটাইমটি বেশ কয়েকটি জায়গায় অনুসন্ধান করে এবং আমি বিশ্বাস করি পরিবেশ অনুসারে আচরণটি পরিবর্তিত হয় (আইআইএস-এ হোস্ট করা কনসোল অ্যাপ্লিকেশন বনাম ইত্যাদি)। আমি অনুমান করি যা বাস্তবায়ন করা উচিত ছিল এটির TryLoadAssembly()অনুরূপ কিছু ছিল ।
অ্যালন গুরালেনেক

63

ভিজ্যুয়াল স্টুডিও প্রকল্পের বৈশিষ্ট্যগুলিতে ("বিল্ড" পৃষ্ঠাতে, আমি যদি এটি ঠিক মনে করি) "বিকল্পটি সিরিয়ালাইজেশন অ্যাসেম্বলি তৈরি করুন" বলে একটি বিকল্প রয়েছে। একটি প্রকল্প যে উত্পন্ন জন্য তে এটি করার চেষ্টা করুন [MyType অ্যাসেম্বলি অফ ধারণকারী]


4
এছাড়াও সিরিয়ালাইজেশন সমাবেশটি যদি ভিজ্যুয়াল স্টুডিওর দ্বারা তৈরি না করা হয় তবে স্ট্যাকওভারফ্লো.com/a/8798289/1164966 দেখুন ।
বেনোইট ব্লাঞ্চন

সেরা, সবচেয়ে পরিষ্কার, সংক্ষিপ্ত উত্তর! আমিও আবার ভোট দিতে পারতাম!
জন জাবরোস্কি

59

তার জন্য একটি কর্মসূচী রয়েছে। আপনি যদি ব্যবহার

XmlSerializer lizer = XmlSerializer.FromTypes(new[] { typeof(MyType) })[0];

এটি ব্যতিক্রম এড়ানো উচিত। এটি আমার পক্ষে কাজ করেছে।

সতর্কতা: একাধিকবার ব্যবহার করবেন না, বা আপনার একটি স্মৃতি ফাঁস হবে

আপনি যদি এই পদ্ধতিটি XmlSerializerএকই ধরণের একাধিকবার উদাহরণ তৈরি করতে ব্যবহার করেন তবে আপনি পাগলের মতো স্মৃতি ফাঁস করবেন !

এর কারণ হল এই পদ্ধতি রোধ করা যাবে অন্তর্নিহিত সরবরাহ করা ক্যাশে XmlSerializer(type)এবং XmlSerializer(type, defaultNameSpace)কন্সট্রাকটর (অন্য সমস্ত এছাড়াও কনস্ট্রাকটর ক্যাশে বাইপাস)।

আপনি যদি কোনও এক্সএমএসআরশায়ালাইজার তৈরি করতে কোনও পদ্ধতি ব্যবহার করেন যা এই দুটি কনস্ট্রাক্টরের মাধ্যমে নয়, আপনাকে অবশ্যই নিজের ক্যাচিং প্রয়োগ করতে হবে বা আপনি মেমরির রক্তক্ষরণ করবেন।


44
সতর্কতা: আপনি XmlSerializerএকই পদ্ধতিতে একাধিকবার উদাহরণ তৈরি করতে যদি এই পদ্ধতিটি ব্যবহার করেন তবে আপনি পাগলের মতো মেমরি ফাঁস করবেন ! এর কারণ হল এই পদ্ধতি রোধ করা যাবে অন্তর্নিহিত সরবরাহ করা ক্যাশে XmlSerializer(type)এবং XmlSerializer(type, defaultNameSpace)কন্সট্রাকটর (অন্য সমস্ত এছাড়াও কনস্ট্রাকটর ক্যাশে বাইপাস)। আপনি যদি এমন কোনও নির্মাণের জন্য কোনও পদ্ধতি ব্যবহার করেন XmlSerializerযা এই দুটি কনস্ট্রাক্টরের মাধ্যমে নয় তবে আপনাকে অবশ্যই নিজের ক্যাচিং বাস্তবায়ন করতে হবে বা আপনি স্মৃতি রক্তক্ষরণ করবেন।
অ্যালন গুরালেনেক

4
@ অ্যালন গুরালেনেক আচ্ছা আমাকে ধিক্কার জানানো হবে ... আপনি একেবারে সঠিক; রিফ্লেক্টরের মাধ্যমে আরও খনন করা দেখায় যে এটি ক্যাশেটি পরীক্ষা করে যখন এটি সিরিয়ালাইজেশন অ্যাসেম্বলি তৈরি করার পরে তা করে ! হাতের কাজ?!?
জেরকিমবল

4
: আউট তার একটি পরিচিত বাগ সক্রিয় weblogs.asp.net/cschittko/archive/2005/01/14/353435.aspx
JerKimball

3
@ জার্কিম্বল: এই পৃষ্ঠাটি আসলে মিথ্যা বলছে না। আপনি আবিষ্কার হিসাবে, FromTypesক্যাশে পপুলেশন প্রদর্শিত হবে না। সুতরাং এটি একটি XmlSerializerবিবৃতিতে খালি ক্যাশে গরম করার একটি বৈধ উপায় হওয়া উচিত (যেমন নিবন্ধটি পরামর্শ দেয়) তবে এটি থেকে কোনও কিছু পুনরুদ্ধার করার জন্য খুব খারাপ উপায় (কেবলমাত্র সহজ নির্মাতাদের মাধ্যমে করা উচিত)। যাই হোক না কেন, আমি জানতাম না এটি একটি বাগ ছিল, আমি সবসময়ই এমন কিছু চিন্তা করতাম যা ফাঁস হওয়ার কথা বলেছিল (আরও উন্নত XmlSerializerনির্মাণকারীদের মতো)) FromTypes()আপনি ঠিক করতে পারেন যেহেতু আমি এমনকি ব্যবহার বিবেচনা করা হবে না types.Select(t => new XmlSerializer(t))
অ্যালন গুরালেনেক

2
@ অ্যালন গুরালেনেক ব্যবহারের অ-পরীক্ষামূলক দিকটির FromTypesআবেদন রয়েছে - এমনকি ছোঁড়া ব্যতিক্রমগুলি সমস্ত ধরা পড়েছে, এটি একটি মূল্যবান অপারেশন; 'ক্যাশে আপনার নিজের উপায়ে' পদ্ধতির একমাত্র কার্যকার্য বলে মনে হচ্ছে, কেবলমাত্র অফিশিয়ালি সমর্থিত ফিক্সটি অস্পষ্ট ওয়েব-ভিত্তিক অ্যাসেমব্লিতে রয়েছে বলে মনে হচ্ছে। (সম্পাদনা করুন: খোলামেলাভাবে, আমি সমস্ত তথ্য ডেটা চুক্তিতে পোর্ট করার জন্য আছি :))
জেরকিমবল

22

আমি এই সঠিক ইস্যুতে দৌড়েছি এবং উল্লিখিত কোনও সমাধানের মাধ্যমে এটি পেতে পারি না।

তারপরে আমি শেষ পর্যন্ত একটি সমাধান খুঁজে পেয়েছি। এটি প্রদর্শিত হয় যে সিরিয়ালাইজারটির জন্য কেবল প্রকারটিই নয়, নেস্টেড টাইপগুলিও প্রয়োজন। এটি পরিবর্তন করা হচ্ছে:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

এটি:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T).GetNestedTypes());

আমার জন্য সমস্যা স্থির। আর কোন ব্যতিক্রম বা কিছুই।


8
এটি আমার পক্ষে কাজ করেছে। .Net4.0 ব্যবহার করে ফর্ম্যাটটি হ'লvar xmlSerializer = new XmlSerializer(typeof(T), typeof(T).GetNestedTypes());
ব্যবহারকারী 3161729

1
এটি আমার পক্ষেও কাজ করেছিল। তবে এটি কেবল সিরিয়ালিংয়ের সময় প্রয়োজনীয় বলে মনে হয়, যখন ডিসিরিয়ালাইজিংয়ের সময় নয়। সম্ভবত এটি বোঝায়, সম্ভবত এটি হয় না।
স্টিভসিংক

2
এটি মেমরি ফাঁস তৈরি করে, যদি প্রচুর সময় চালায়।
ভোলাডাইমার কোটিলো

9

সিরিয়ালাইজার তৈরি করতে আমার সমাধানটি হ'ল সরাসরি প্রতিচ্ছবিতে to এটি ব্যতিক্রমী ফাইল লোডিংকে বাইপাস করে। আমি এটি একটি সহায়ক ফাংশনে প্যাকেজ করেছি যা সিরিয়ালাইজারকে ক্যাশে করার ক্ষেত্রেও যত্ন নেয়।

private static readonly Dictionary<Type,XmlSerializer> _xmlSerializerCache = new Dictionary<Type, XmlSerializer>();

public static XmlSerializer CreateDefaultXmlSerializer(Type type) 
{
    XmlSerializer serializer;
    if (_xmlSerializerCache.TryGetValue(type, out serializer))
    {
        return serializer;
    }
    else
    {
        var importer = new XmlReflectionImporter();
        var mapping = importer.ImportTypeMapping(type, null, null);
        serializer = new XmlSerializer(mapping);
        return _xmlSerializerCache[type] = serializer;
    }
}

এখানে 2 টি সমস্যা - প্রথমে আপনার কোডটি থ্রেড-নিরাপদ নয় এবং দ্বিতীয়টি (আরও গুরুত্বপূর্ণভাবে) আপনি। নেট রানটাইমটি ইতিমধ্যে কী ঘটেছে (আপনি ব্যবহার করছেন এমন কর্টারের উপর ভিত্তি করে) প্রতিলিপি দেওয়ার চেষ্টা করছেন। অর্থাত্ এই
ডেভ ব্ল্যাক

@ ডেভ ব্ল্যাক: হ্যাঁ, একটি সমকালীন অভিধানে ক্যাচ দিয়ে চতুর্ভুজটির উত্তর আরও ভাল হবে
ডি - বি

@db আমার ২ য় পয়েন্টটি ছিল যে ক্যাচিংয়ের প্রয়োজন হয় না - যতক্ষণ আপনি ফ্রেমওয়ার্কটি ক্যাশে করে এমন দুটি সেন্টারের একটি ব্যবহার করছেন (ওপি প্রথমটি ব্যবহার করছে)। এমএসডিএন থেকে: কর্মক্ষমতা বাড়াতে, এক্সএমএল সিরিয়ালাইজেশন অবকাঠামো নির্দিষ্ট ধরণের সিরিয়ালাইজ এবং ডিসাইরিয়ালাইজ করার জন্য গতিশীলভাবে অ্যাসেমব্লি তৈরি করে। ফ্রেমওয়ার্কটি সেই অ্যাসেমব্লিকে সন্ধান করে এবং পুনরায় ব্যবহার করে। এই আচরণ কেবল ঘটে যখন নিম্নলিখিত ctors ব্যবহার করছে: XmlSerializer.XmlSerializer (প্রকার) XmlSerializer.XmlSerializer (প্রকার, STRING) রেফারেন্স: msdn.microsoft.com/en-us/library/...
ডেভ ব্ল্যাক

@ ডেভব্ল্যাক: হ্যাঁ, তবে ব্যবহারগুলি সম্পূর্ণরূপে বৈধ হলেও এমনকি এই নির্মাণকারীরা অভ্যন্তরীণভাবে একটি ব্যতিক্রম ছুঁড়ে ফেলেন এবং ধরেন। এটি খারাপ, এবং এই কারণেই ওপি প্রথম স্থানে প্রশ্ন জিজ্ঞাসা করেছিল।
d - বি

@db সত্য, তবে আমি যা বলতে চাইছিলাম (তবে স্পষ্ট ছিল না - আমার ক্ষমা চেয়েছি) তা হ'ল যে আপনার দ্রাবণের একমাত্র লাইনগুলি প্রয়োজনীয় তা অন্য শর্তের প্রথম 3 লাইন।
ডেভ ব্ল্যাক

8

ব্যতিক্রম এড়াতে আপনার দুটি জিনিস করা দরকার:

  1. ক্রমিক শ্রেণিতে একটি বৈশিষ্ট্য যুক্ত করুন (আমি আশা করি আপনার অ্যাক্সেস রয়েছে)
  2. Sgen.exe দিয়ে সিরিয়ালাইজেশন ফাইল তৈরি করুন

আপনার ক্লাসে সিস্টেম.এক্সএমএল.আরশিয়ালাইজেশন। এক্সএমএলসিরাইজারঅ্যাস্যাসব্যাট বৈশিষ্ট্য যুক্ত করুন। মাই ক্লাস যেখানে রয়েছে সেই সমাবেশের নাম দিয়ে 'মায়আসাপ্যুলস' প্রতিস্থাপন করুন।

[Serializable]
[XmlSerializerAssembly("MyAssembly.XmlSerializers")]
public class MyClass
{

}

Sgen.exe ইউটিলিটি ব্যবহার করে সিরিয়ালাইজেশন ফাইল তৈরি করুন এবং শ্রেণীর সমাবেশে এটি স্থাপন করুন।

'sgen.exe MyAsorses.dll' ফাইলটি MyAsorses.XMLSerializers.dll তৈরি করবে

এই দুটি পরিবর্তনের ফলে। নেট সরাসরি অ্যাসেম্বলি সন্ধান করতে পারে। আমি এটি পরীক্ষা করেছিলাম এবং এটি ভিজুয়াল স্টুডিও ২০০৮ এর সাথে .NET ফ্রেমওয়ার্ক 3.5 এ কাজ করে


ঠিক আছে, এবং এই পরিবর্তনগুলি ছাড়া এটি ব্যর্থ হয়েছিল, এবং যদি তাই হয় তবে কেন?
জন স্যান্ডার্স

1
আমার প্রকল্প, ভিএস2012-তে 4.0 কেন হঠাৎ ব্যর্থ হতে শুরু করল তার কোনও কারণ খুঁজে পাচ্ছি না। ত্রুটিটিকে "উপেক্ষা করা" কোনও বিকল্প ছিল না, কারণ আমি যখনই অ্যাক্টিভ ডিরেক্টরিতে অ্যাক্সেস করার চেষ্টা করেছি তখনই এটি ঘটেছিল; সুতরাং উপেক্ষা করার অর্থ প্রমাণীকরণ নয়। আমি এখনও খুব হতাশ হয়েছি যে ভিএস ২০১২ সঠিকভাবে সিরিয়ালাইজেশন ডিএলএল স্বয়ংক্রিয়ভাবে উত্পন্ন করবে না। যাইহোক, এই পদক্ষেপগুলি সঠিক সমাধান সরবরাহ করে।
sfuqua

6

এই ব্যতিক্রমটিকে বাইন্ডিংফেইলর নামে পরিচিত একটি পরিচালিত ডিবাগিং সহকারী (এমডিএ) দ্বারা আটকাতেও পারে।

যদি আপনার অ্যাপ্লিকেশনটি প্রাক-বিল্ড সিরিয়ালাইজেশন অ্যাসেম্বলগুলি সহ শিপ করার জন্য ডিজাইন করা থাকে তবে এই এমডিএ দরকারী। আমরা আমাদের অ্যাপ্লিকেশনটির কর্মক্ষমতা বাড়ানোর জন্য এটি করি। এটি আমাদের নিশ্চিত করতে দেয় যে প্রাক বিল্ট সিরিয়ালাইজেশন অ্যাসেম্বলিসগুলি সঠিকভাবে আমাদের বিল্ড প্রক্রিয়া দ্বারা নির্মিত হচ্ছে এবং ফ্লাইতে পুনরায় তৈরি না করে অ্যাপ্লিকেশন দ্বারা লোড করা হচ্ছে।

এটি এই দৃশ্যপট ব্যতীত সত্যই কার্যকর নয়, কারণ অন্যান্য পোস্টাররা যেমন বলেছে যে সিরিয়ালাইজার কনস্ট্রাক্টর যখন একটি বাধ্যতামূলক ত্রুটি আটকা পড়ে তখন সিরিয়ালাইজেশন অ্যাসেমব্লি রানটাইমে পুনর্নির্মাণ হয়। সুতরাং আপনি সাধারণত এটি বন্ধ করতে পারেন।


6

ফাংশন এক্সএমএলসায়ারালাইজার.ফ্র্যামটাইপগুলি ব্যতিক্রমটি ছুঁড়ে না ফেলে তবে মেমরি ফাঁস করে দেয়। আপনার তৈরি প্রতিটি উদাহরণের জন্য মেমরি ফাঁস হওয়া এড়াতে আপনাকে কেন এই ধরণের সিরিয়ালাইজারটি প্রতিটি ধরণের জন্য ক্যাশে করতে হবে তা ঠিক।

আপনার নিজের এক্সএমএলসিরাইজার কারখানা তৈরি করুন এবং এটি সহজভাবে ব্যবহার করুন:

XmlSerializer serializer = XmlSerializerFactoryNoThrow.Create(typeof(MyType));

কারখানাটি দেখতে পছন্দ করে:

public static class XmlSerializerFactoryNoThrow
{
    public static Dictionary<Type, XmlSerializer> _cache = new Dictionary<Type, XmlSerializer>();

    private static object SyncRootCache = new object();        

    /// <summary>
    /// //the constructor XmlSerializer.FromTypes does not throw exception, but it is said that it causes memory leaks
    /// http://stackoverflow.com/questions/1127431/xmlserializer-giving-filenotfoundexception-at-constructor
    /// That is why I use dictionary to cache the serializers my self.
    /// </summary>
    public static XmlSerializer Create(Type type)
    {
        XmlSerializer serializer;

        lock (SyncRootCache)
        {
            if (_cache.TryGetValue(type, out serializer))
                return serializer;
        }

        lock (type) //multiple variable of type of one type is same instance
        {
            //constructor XmlSerializer.FromTypes does not throw the first chance exception           
            serializer = XmlSerializer.FromTypes(new[] { type })[0];
            //serializer = XmlSerializerFactoryNoThrow.Create(type);
        }

        lock (SyncRootCache)
        {
            _cache[type] = serializer;
        }
        return serializer;
    }       
}

মেমরি ফাঁস হওয়ার সম্ভাবনা ছাড়াই আরও জটিল সংস্করণ (দয়া করে কেউ কোডটি পর্যালোচনা করুন):

    public static XmlSerializer Create(Type type)
    {
        XmlSerializer serializer;

        lock (SyncRootCache)
        {
            if (_cache.TryGetValue(type, out serializer))
                return serializer;
        }

        lock (type) //multiple variable of type of one type is same instance
        {
            lock (SyncRootCache)
            {
                if (_cache.TryGetValue(type, out serializer))
                    return serializer;
            }
            serializer = XmlSerializer.FromTypes(new[] { type })[0];
            lock (SyncRootCache)
            {
                _cache[type] = serializer;
            }
        }          
        return serializer;
    }       
}

পরিবর্তে আপনার সমকালীন অভিধান ব্যবহার করা উচিত। এই কোড ডেডলক করতে পারে।
বেহরোজ

অভিধান সহ সমস্ত ব্যবস্থাপনা লক বিভাগে থাকলে কীভাবে এটি অচল থাকতে পারে?
টমাস কুবেস

দুঃখিত, আমি শব্দ গুলিয়ে গেলাম। আমি যা বোঝাতে চেয়েছি তা হ'ল এটি একবারে একাধিক আইটেম .োকাতে পারে। কারণ এটি যখন অস্তিত্বের জন্য পরীক্ষা করে এবং কখন এটি সন্নিবেশ করে তার মধ্যে একটি ব্যবধান থাকে। সমবর্তী অভিধানে কিছু ধরণের দ্বি-পর্যায়ের লকিং (ব্যাগ [0] এবং তারপরে ব্যাগ [হ্যাশ]] ব্যবহার করা হয় এবং ব্যাগটির একটি উল্লেখ রাখা হয় যা আপনার কাজ করা আইটেমটি অবশ্যই sertোকাতে / রাখতে হবে। এটি দ্রুত, নিরাপদ এবং ক্লিনার।
বেহরোজ

হ্যা এবং না. আপনি ঠিক বলেছেন যে এটি ঘটতে পারে একই সময়ে একই ধরণের একটি সিরিয়াল সমান্তরালভাবে দুটি থ্রেডে তৈরি করা হবে এবং তারপরে অভিধানে দু'বার যুক্ত করা হবে। এই ক্ষেত্রে দ্বিতীয় সন্নিবেশ কেবল প্রথমটিকে প্রতিস্থাপন করবে তবে লক বিভাগ গ্যারান্টির থ্রেড সুরক্ষা এবং সামগ্রিক অসুবিধা হ'ল ছোট মেমরি ফাঁস। এটি পারফরম্যান্স অপটিমাইজেশন, কারণ আপনি টাইপের সিরিয়ালাইজারের সাথে থ্রেডটি চাইছেন না, আসল দৃশ্যে বি টাইপের বি সিরিয়ালের সাহায্যে থ্রেড দু'টি দ্বারা ব্লক করা উচিত।
টমাস কুবেস

আমি কল্পনা করতে পারি সমাধানটি আরও ভাল হতে পারে (তাত্ত্বিক মেমরি ফাঁস ছাড়াই) তবে আরও জটিল।
টমাস কুবেস

3

অন্যদিকে সমস্যা সমাধানের সংকলন ত্রুটিগুলি অত্যন্ত জটিল। এই সমস্যাগুলি বার্তা সহ একটি ফাইলনটফাউন্ড এক্সপ্লেসে নিজেকে প্রকাশ করে:

File or assembly name abcdef.dll, or one of its dependencies, was not found. File name: "abcdef.dll"
   at System.Reflection.Assembly.nLoad( ... )
   at System.Reflection.Assembly.InternalLoad( ... )
   at System.Reflection.Assembly.Load(...)
   at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly() 

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

দ্রষ্টব্য এই ত্রুটিটি তখনও ঘটে যখন কোনও অ্যাকাউন্ট বা সুরক্ষা পরিবেশে টেম্প ডিরেক্টরিটি অ্যাক্সেস করতে সক্ষম না হয়ে চালানো হয় runs

সূত্র : http://msdn.microsoft.com/en-us/library/aa302290.aspx


তিনি রানটাইমে এই হ্যাপেনড উল্লেখ করেননি। আরেকটি বিষয় আমি ভাবতে পারি যে আপনার সম্ভবত একটি নেমস্পেস / শ্রেণি দ্বন্দ্ব রয়েছে। আপনার মাইটাইপের পুরো নাম কি?
জিফ্র্যাক্স

হ্যাঁ, আমি আপনার লিঙ্কটি যাচাই করেছিলাম, কনস্ট্রাক্টরগুলির তথ্য, যদিও সহায়ক, তবে আমার প্রয়োজন ছিল না।
ইরভিন

5
@ স্পেসেঘোস্টআল আপনি রানটাইমে সংকলন করতে পারেন। এবং এটি এক্সএমএলসিরাইজারই করে। এটি গতিশীলভাবে রানটাইমে একটি অ্যাসেমব্লি তৈরি করে যা (ডি) নির্দিষ্ট ধরণের জন্য এক্সএমএলকে সিরিয়ালাইজ করে। যে কোনও কারণেই এই প্রক্রিয়াটি ওপিতে ব্যর্থ হয়। সম্ভবত অনুমোদনের সমস্যাগুলির কারণে যেমন একটি অস্থায়ী ডিরেক্টরিতে। (ডিস্কের স্থান থেকে আরও যেমন নিরীহ যেমন হতে পারে।)
টি

আপনি যদি এই বিষয়ে নিশ্চিত? আমি নিশ্চিত ছিলাম যে সিরিয়ালাইজেশন স্টাফ বিল্ড চলাকালীন আপনার অ্যাসবেশননাম.এক্সএমএলসরিয়ালিয়ারস.ডি.এল নামে একটি অ্যাসেমব্লিতে সংকলিত হয়, রানটাইম সময়ে সংকলিত হয় না। এটি সমস্ত ধরণের কারণে ব্যর্থ হতে পারে, মোতায়েন ফোল্ডারে কমপক্ষে সমস্ত এনটিএফএসের অনুমতি।
tomfanning

1
আমি এই একাধিকবার upvote করতে চান। টেম্পোর ফোল্ডারটি অ্যাক্সেস করতে না পারার বিষয়ে অ্যাকাউন্ট সম্পর্কে আপনার নোটটি আমার জন্য উত্তরকে ট্রিগার করেছিল। একবার আমি সার্ভারে প্রশাসনিক গোষ্ঠীতে আমার পরিষেবা অ্যাকাউন্ট যুক্ত করলে এটি সবেমাত্র কাজ করে। ধন্যবাদ!
বব হর্ন

2

ভিজ্যুয়াল স্টুডিও প্রকল্পের বৈশিষ্ট্যগুলিতে "সিরিয়ালাইজেশন অ্যাসেম্বলি উত্পন্ন করুন" বলে একটি বিকল্প রয়েছে। এমন একটি প্রকল্পের জন্য এটি চালু করার চেষ্টা করুন যা [মাইটাইপের সমাবেশ সহ] উত্পন্ন করে gene


1

সিরিয়াল করার জন্য একটি কাস্টম ক্লাস:

[Serializable]
public class TestClass
{
    int x = 2;
    int y = 4;
    public TestClass(){}
    public TestClass(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int TestFunction()
    {
        return x + y;
    }
}

আমি কোড স্নিপেট সংযুক্ত করেছি। হতে পারে এটি আপনাকে সাহায্য করতে পারে।

static void Main(string[] args)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(TestClass));

    MemoryStream memoryStream = new MemoryStream();
    XmlTextWriter xmlWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

    TestClass domain = new TestClass(10, 3);
    xmlSerializer.Serialize(xmlWriter, domain);
    memoryStream = (MemoryStream)xmlWriter.BaseStream;
    string xmlSerializedString = ConvertByteArray2Str(memoryStream.ToArray());

    TestClass xmlDomain = (TestClass)DeserializeObject(xmlSerializedString);

    Console.WriteLine(xmlDomain.TestFunction().ToString());
    Console.ReadLine();
}

2
-1 রিসোর্স ফাঁস রোধে ব্লক ব্যবহার না করার জন্য এবং এক্সএমএলেক্সট রাইটার ব্যবহার করার জন্য।
জন স্যান্ডার্স 16

ঠিক আছে একমত, তবে তবুও আমি এক্সএমএসআরশায়ালার এক্সএমএলসিরাইজার = নতুন এক্সএমএলসিরাইজার (টাইপফ (টেস্টক্লাস)) ব্যবহার করেছি; তবে আমি এই ব্যতিক্রমটি পাচ্ছি না।
শাহজাপান

1

আমারও একই সমস্যা ছিল, এবং ব্যতিক্রম উপেক্ষা করা আমার পক্ষে কার্যকর হয়নি। আমার কোডটি এনএসওয়ারবাসের কনফিগারেশনটিকে কল করছিলConfigure.With(...).XmlSerializer()...

এটি আমার জন্য কী ঠিক করেছিল তা হ'ল আমার প্রকল্পের প্ল্যাটফর্মটি পরিবর্তন করা।

  1. বিল্ড \ কনফিগারেশন ম্যানেজারে যান ...
  2. আপনার প্রকল্পটি সন্ধান করুন এবং প্ল্যাটফর্মটি পরিবর্তন করুন (x86 থেকে যে কোনও সিপিইউতে আমার ক্ষেত্রে)

1

ঠিক যেমন রেফারেন্স। ডিবি উত্তর এবং মন্তব্যগুলি গ্রহণ করে, আমি এই সমাধানটি নিয়ে এসেছি যা ডিবি সমাধানের কাছাকাছি। এটি আমার সমস্ত ক্ষেত্রে সূক্ষ্মভাবে কাজ করে এবং এটি থ্রেড নিরাপদ। আমি মনে করি না যে সমকালীন অভিধান ব্যবহার করা ঠিক ছিল would

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace HQ.Util.General
{
    public class XmlSerializerHelper
    {
        private static readonly Dictionary<Type, XmlSerializer> _dictTypeToSerializer = new Dictionary<Type, XmlSerializer>();

        public static XmlSerializer GetSerializer(Type type)
        {
            lock (_dictTypeToSerializer)
            {
                XmlSerializer serializer;
                if (! _dictTypeToSerializer.TryGetValue(type, out serializer))
                {
                    var importer = new XmlReflectionImporter();
                    var mapping = importer.ImportTypeMapping(type, null, null);
                    serializer = new XmlSerializer(mapping);
                    return _dictTypeToSerializer[type] = serializer;
                }

                return serializer;
            }
        }
    }
}

ব্যবহার:

        if (File.Exists(Path))
        {
            using (XmlTextReader reader = new XmlTextReader(Path))
            {
                // XmlSerializer x  = new XmlSerializer(typeof(T));
                var x = XmlSerializerHelper.GetSerializer(typeof(T));

                try
                {
                    options = (OptionsBase<T>)x.Deserialize(reader);
                }
                catch (Exception ex)
                {
                    Log.Instance.AddEntry(LogType.LogException, "Unable to open Options file: " + Path, ex);
                }
            }
        }

0

আপনার ধরণটি অন্যান্য সমাবেশগুলিতে রেফারেন্স দিতে পারে যা জিএসি বা আপনার স্থানীয় বিন ফোল্ডারে ==> খুঁজে পাওয়া যায় না ...

"বা এর একটি নির্ভরতা The সিস্টেম নির্দিষ্ট ফাইলটি খুঁজে পায় না"

আপনি যে ধরণের সিরিয়ালাইজ করতে চান তার উদাহরণ দিতে পারেন?

দ্রষ্টব্য: আপনার ধরণটি সিরিয়ালাইজযোগ্য প্রয়োগ করে তা নিশ্চিত করুন।


0

আমি একই ত্রুটি পেয়েছিলাম, এবং এটি যে ধরণের আমি ডিফল্ট প্যারামিটারলেস কনস্ট্রাক্টর না থাকার কারণে ডিজিটালাইজ করার চেষ্টা করছিলাম তার কারণে এটি হয়েছিল । আমি একটি কনস্ট্রাক্টর যুক্ত করেছি, এবং এটি কাজ শুরু করে।


0

আমি এক্সএসডি থেকে ক্লাস তৈরি করতে তৃতীয় পক্ষের সরঞ্জাম ব্যবহার না করা পর্যন্ত আমার একই সমস্যা ছিল এবং এটি কার্যকর হয়েছিল! আমি আবিষ্কার করেছি যে সরঞ্জামটি আমার শ্রেণীর শীর্ষে কিছু অতিরিক্ত কোড যুক্ত করছে। যখন আমি এই একই কোডটি আমার মূল শ্রেণীর শীর্ষে যুক্ত করেছিলাম তখন এটি কাজ করেছিল। আমি যা যুক্ত করেছি তা এখানে ...

#pragma warning disable
namespace MyNamespace
{
  using System;
  using System.Diagnostics;
  using System.Xml.Serialization;
  using System.Collections;
  using System.Xml.Schema;
  using System.ComponentModel;
  using System.Xml;
  using System.Collections.Generic;

  [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
  [System.SerializableAttribute()]
  [System.Diagnostics.DebuggerStepThroughAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
  public partial class MyClassName
  {
  ...

0

একটি ব্যবহার করার জন্য প্রচুর সুপারিশ দেখেছি ConcurrentDictionary, তবে এর কোনও দৃ examples় উদাহরণ নেই, তাই আমি আমার টুপিটিকে সমাধানের দৌড়ে ফেলতে যাচ্ছি। আমি কোনও থ্রেড-নিরাপদ বিকাশকারী নই, সুতরাং এই কোডটি শক্ত না হলে দয়া করে যারা অনুসরণ করেন তাদের পক্ষে কথা বলুন।

public static class XmlSerializerHelper
{
    private static readonly ConcurrentDictionary<Type, XmlSerializer> TypeSerializers = new ConcurrentDictionary<Type, XmlSerializer>();

    public static XmlSerializer GetSerializer(Type type)
    {
        return TypeSerializers.GetOrAdd(type,
        t =>
        {
            var importer = new XmlReflectionImporter();
            var mapping = importer.ImportTypeMapping(t, null, null);
            return new XmlSerializer(mapping);
        });
    }
}

আমি মূল্য যুক্ত করে ConcurrentDictionaryএবং Lazyলোড অন্যান্য পোস্ট দেখেছি । আমি এখানে প্রাসঙ্গিক কিনা তা নিশ্চিত নই, তবে এর জন্য কোডটি এখানে:

private static readonly ConcurrentDictionary<Type, Lazy<XmlSerializer>> TypeSerializers = new ConcurrentDictionary<Type, Lazy<XmlSerializer>>();

public static XmlSerializer GetSerializer(Type type)
{
    return TypeSerializers.GetOrAdd(type,
    t =>
    {
        var importer = new XmlReflectionImporter();
        var mapping = importer.ImportTypeMapping(t, null, null);
        var lazyResult = new Lazy<XmlSerializer>(() => new XmlSerializer(mapping), LazyThreadSafetyMode.ExecutionAndPublication);
        return lazyResult;
    }).Value;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.