Cannot lock xml write using lock() or Mutex - multithreading

I am writing a simple application which writes to a single xml file for around 1000 iterations from multiple threads .
I have tried using the lock() ,Mutex and the ReaderWriterSlim to lock the file while its being written. It works for some time but gives error about the file is being accessed by another process.
Can somebody please help me to get some solution :
Or is there any other way to achieve this .
public class XmlWrite
{
//private static object _lock = new Object();
static string xmlFilePath = "C:\\Test\\Multi.xml";
public static Mutex m_Mutex = new Mutex(false, #"Global\MyMutex");
public static void LogXML(object threadID)
{
int i = 0;
while (i < 1000)
{
try
{
m_Mutex.WaitOne();
XmlDocument xml = LoadDocument(xmlFilePath);
var xmlElement = XElement.Load(new XmlNodeReader(xml));
var sourceXElement = new XElement("ParentNode");
sourceXElement.Add(new XElement("ChildNode", threadID));
xmlElement.Add(sourceXElement);
SaveDocument(xmlElement, xmlFilePath);
Console.WriteLine("Value " + xml.ToString() + "Index" + i + "Thread" + threadID.ToString());
}
catch (Exception exe)
{
Console.WriteLine(exe.Message);
}
finally
{
m_Mutex.ReleaseMutex();
}
i = i + 1;
}
}
public static XmlDocument LoadDocument(String path)
{
XmlDocument document = new XmlDocument();
using (StreamReader stream = new StreamReader(path, Encoding.GetEncoding("iso-8859-7")))
{
document.Load(stream);
}
return (document);
}
public static XElement SaveDocument(XElement document, String path)
{
using (StreamWriter stream = new StreamWriter(path, false, Encoding.GetEncoding("iso-8859-7")))
{
document.Save(stream);
}
return (document);
}
}
class Program
{
static void Main(string[] args)
{
new Thread(XmlWrite.LogXML).Start("A");
new Thread(XmlWrite.LogXML).Start("B");
new Thread(XmlWrite.LogXML).Start("C");
new Thread(XmlWrite.LogXML).Start("D");
new Thread(XmlWrite.LogXML).Start("E");
new Thread(XmlWrite.LogXML).Start("F");
new Thread(XmlWrite.LogXML).Start("G");
new Thread(XmlWrite.LogXML).Start("H");
new Thread(XmlWrite.LogXML).Start("i");
}
}

Related

Concurrent writing elements into the ConcurrentHashMap admits element

Concurrent writing elements into the ConcurrentHashMap admits element. Requirements: writing must be done in different threads. Is there way to use advantages of the ConcurrentHashMap and do writing without blocking and sleeping?
Is there good code for iterator that accessed from different treads. Or is there other good variant to keep ieratian looking on the effectively-final requirement?
public class Task3v2 {
public static void main(String[] args) {
System.out.println("ConcurrentHashMap : "+timeIt(new ConcurrentHashMap<Integer, String>()));
}
static Iterator<Integer> integerIterator;
static {createIterator();}
private static void createIterator() {
integerIterator=
Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList()).iterator();
}
public static double timer(Runnable block) {
long start = System.nanoTime();
try {
block.run();
} finally {
long end = System.nanoTime();
return(end - start);
}
}
public static double timeIt(Map<Integer, String> map){
return timer(
()->{
new Thread(()->{
fillMap(map);
System.out.println("invoked");
readMap(map);
}).start();
});
}
private static void fillMap(Map<Integer, String> map){
int[] index = new int[1];
String[] tmp = new String[1];
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i< 100; i++){
index[0] = i;
tmp[0] = "Name"+i;
new Thread(()->{
int a = integerIterator.next();
System.out.println("a :"+a);
map.put(a,"Name"+a);
}
).start();
}
}
private static void readMap(Map<Integer, String> map){
int[] index2 = new int[1];
for(int i = 0; i< 100; i++){
index2[0]=i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
System.out.println("map.get(index2[0]) :"+map.get(index2[0]));
}).start();
}
}
}
Finally the map must pass following tests:
public class Task3Test {
static ConcurrentHashMap<Integer, String> map;
#BeforeClass
public static void fillMap(){
map = new ConcurrentHashMap<>();
timeIt(map);
}
#Test
public void elementPresenceTest(){
//GIVEN
//map;
//WHEN
List<Integer> actualPresenceList = Stream.iterate(0, i -> i + 1).limit(100)
.filter(n->(map.entrySet().stream().map(Map.Entry::getKey)
.anyMatch(m->(n.equals(m))))).collect(Collectors.toList());
actualPresenceList.forEach(System.out::println);
System.out.println("size"+actualPresenceList.size());
//THEN
List<Integer>expectedPresenceList = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList());
assertThat(actualPresenceList, Matchers.contains(expectedPresenceList));
}
#Test
public void elementAmountTest() {
assertThat(map.entrySet(), Matchers.hasSize(100));
}
}
Iterator is not acceptable for concurrency. Solution is:
static Queue integerQueue = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toCollection(LinkedBlockingQueue::new));
There is needed to keep sleeping for the readMap() method to provide time for the writing method. If there is needed to keep any data structure on adding new elements in concurrency environment, it should be used queue instead of map.

How to make clone of static variables of static class in c#

I am working on different approaches of cloning of an objects in c# but currently I stuck with the simple one. I have a static class with static variables & I want to make an exact copy of one of my static variable.I have sketched my code structure below:
public static class RULE_SET
{
public static bool IsdataValid;
public static GCBRequest GCBData;
public static T Clone<T>(this T source)
{
try
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
catch (Exception ee) { return default(T); }
}
}
[XmlRoot(ElementName = "GCBRequest")]
public class GCBRequest
{
[XmlElement(ElementName = "PID")]
public string PID { get; set; }
[XmlElement(ElementName = "AID")]
public string AID { get; set; }
[XmlElement(ElementName = "CID")]
public string CID { get; set; }
}
//code to load the RULE_SET
string strJsonRuleset = "{\r\n \"GCdBINRequest\": {\r\n\"PID\": \"(?s).*#M#20\",\r\n\"AID\": \"(?s).*#O#10\",\r\n\"CID\": \"(?s).*#O#25\"\r\n }\r\n}";
public class RULE_SET_LOCAL
{
public static GCBRequest GCBData;
}
//from other method
RULE_SET_LOCAL objParentRuleSet = new RULE_SET_LOCAL();
objParentRuleSet = JsonConvert.DeserializeObject<RULE_SET_LOCAL>(strJsonRuleset);
RULE_SET.GCBData = objParentRuleSet.GCBData;
//Main Method from which I have to create a clone object
Object objRuleset;
objRuleset = RULE_SET.GCBData.Clone();
if(objRuleset == null)
{
** stuck here**
I don't know why Everytime I got the null object ?
}
// but I have use
objRuleset = RULE_SET.GCBData;
if(objRuleset != null)
{
** Successfully reached **
//But I can't do any operation on this object as it will effect the original one.
}
Guys, Do you have any solution/Suggestion ?
Please help me to understand this , any help will be appreciated.
Thanks.
After searching a lot I got this method :
public static T Clone<T>(this T source)
{
var serialized = JsonConvert.SerializeObject(source);
return JsonConvert.DeserializeObject<T>(serialized);
}
& now I am able to get the clone by calling
object objRuleset = RULE_SET.Clone<GCBRequest>(RULE_SET.GCBData);

the specified child already has a parent .you must call removeView()

For some reason, I keep receiving the following error:
java.lang.IllegalStateException: the specified child already has a parent. You must call removeView() on the child's parent view
I am using the following code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listitem);
//url is fetched from another class
readWebpage(imdbUrl);
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
}
#Override
protected void onPostExecute(String result) {
//textView.setText(result);
displayMoviesList(result);
}
}
public void readWebpage(String imdbUrl) {
}
public void displayMoviesList(String result) {
JSONObject responseObj = null;
try {
responseObj = new JSONObject(result);
JSONObject Obj = responseObj.getJSONObject("results");
JSONArray moviesListObj = Obj.getJSONArray("result");
for(int i=0 ;i<moviesListObj.length();i++) {
JSONObject e = moviesListObj.getJSONObject(i);
cover[i] = e.getString("cover");
title[i] = e.getString("title");
year[i] = e.getString("year");
director[i] = e.getString("director");
rating[i] = e.getString("rating");
details[i] = e.getString("details");
}
tl = (TableLayout) findViewById(R.id.main_table);
imgView = (ImageView)findViewById(R.id.imageID);
progressbar = (ProgressBar) findViewById(R.id.loadingBar);
//new loadImageTask().execute(cover[i].toString());
new loadImageTask().execute( URL);// it calls another function..
TextView title = (TextView)findViewById(R.id.titleID);
title.setText("TEXT");
TableRow tr = new TableRow(this);
tr.addView(imgView);
tr.addView(title);
tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
} catch(JSONException e) {
//Log.e("log_tag", "Error parsing data " + e.toString());
}
I am not sure why I'm receiving the error, but it appears to be being generated while I am adding it to the view.
Solution is that we either we define the rows in .xml file or in our .java file. I was adding the rows dynamically in my java file and using addView. So in .xml file we cannot add another view (we should not add rows for the same).

Multithreading and file I/O , ThreadLocal issues

I have this base class structure:
Base:
public abstract class BackgroundTask
{
protected readonly Logger Logger = LogManager.GetCurrentClassLogger();
protected virtual void Initialize()
{
// initialize database access
}
public void Run()
{
Initialize();
try
{
Execute();
// insert to database or whatever
}
catch (Exception ex)
{
Logger.ErrorException(string.Format("Error proccesing task: {0}\r\n", ToString()), ex);
Exceptions.Add(ex);
}
finally
{
TaskExecuter.Discard();
}
}
protected abstract void Execute();
public abstract override string ToString();
public IList<Exception> Exceptions = new List<Exception>();
}
Task executor:
public static class TaskExecuter
{
private static readonly ThreadLocal<IList<BackgroundTask>> TasksToExecute
= new ThreadLocal<IList<BackgroundTask>>(() => new List<BackgroundTask>());
public static void ExecuteLater(BackgroundTask task)
{
TasksToExecute.Value.Add(task);
}
public static void StartExecuting()
{
foreach (var backgroundTask in TasksToExecute.Value)
{
Task.Factory.StartNew(backgroundTask.Run);
}
}
public static void Discard()
{
TasksToExecute.Value.Clear();
TasksToExecute.Dispose();
}
}
FileTask:
public class FileTask : BackgroundTask
{
protected static string BaseFolder = #"C:\ASCII\";
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
private readonly string _folder;
private IHistoryRepository _historyRepository;
public string Folder
{
get { return _folder; }
}
public FileTask(string folder)
{
_folder = string.Format("{0}{1}", BaseFolder, folder);
}
protected override void Initialize()
{
_historyRepository = new HistoryRepository();
}
protected override void Execute()
{
// todo: Get institute that are active,
var institute = MockInstitute(); // todo: uncomment _historyRepository.FindInstituteByFolderName(Folder);
// todo: Update institute, lastupdate - [date] | [files amount] | [phonenumbers amount]
if (institute == null)
{
Logger.Warn("Not found data", Folder);
return;
}
// todo: read file get encoding | type and parse it
Task.Factory.StartNew(ReadFile);
}
private void ReadFile()
{
var list = GetFilesByFolder();
StreamReader sr = null;
try
{
Lock.EnterReadLock();
foreach (var fi in list)
{
var fileName = fi.FullName;
Logger.Info("Line: {0}:=> Content: {1}", fileName, Thread.CurrentThread.ManagedThreadId);
sr = new StreamReader(fileName, DetectEncoding(fileName));
string currentLine;
while ((currentLine = sr.ReadLine()).ReturnSuccess())
{
if (string.IsNullOrEmpty(currentLine)) continue;
Logger.Info("Line: {0}:=> Content: {1}", fileName, currentLine);
}
}
Lock.ExitReadLock();
}
finally
{
if (sr != null) sr.Dispose();
Logger.Info("Finished working" + Folder);
}
}
protected IEnumerable<FileInfo> GetFilesByFolder()
{
return Directory.GetFiles(Folder).Select(fileName => new FileInfo(fileName));
}
protected Encoding DetectEncoding(string file)
{
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var cdet = new Ude.CharsetDetector();
cdet.Feed(fs);
cdet.DataEnd();
return cdet.With(x => x.Charset)
.Return(x => Encoding.GetEncoding(cdet.Charset),
Encoding.GetEncoding("windows-1255"));
}
}
private Institute MockInstitute()
{
return new Institute
{
FromFolderLocation = string.Format("{0}{1}", BaseFolder, Folder)
};
}
public override string ToString()
{
return string.Format("Folder: {0}", Folder);
}
}
When don't read the file every thing ok, the Log is populated and every thing runs smooth,
but when i attach the Task.Factory.StartNew(ReadFile); method i have an exception.
Exception:
Cannot access a disposed object.
Object name: 'The ThreadLocal object has been disposed.'.
How do i solve that issue? might i need to change the LocalThread logic, or what - i have been trying to handle that issue, for almost a day.
BTW: It's an MVC4 project, and C# 5.0 and i'm trying to TDD it all.
You shouldn't be calling TasksToExecute.Dispose();
there.

Getting error while calling library jar file in j2me

I have created a login page with webservice in j2me. But while running I am getting error. Can anyone please help? My code is:
public class Login extends MIDlet implements CommandListener {
//the main form
Form mainForm = null;
//the text-boxes for the input
TextField txtBoxA = null;
TextField txtBoxB = null;
//the result label
//the Exit command
Command cmdExit = null;
Command cmdAdd = null;
//the Display reference
Display display = null;
public Login() {
{
//construct the main form
mainForm = new Form("kSOAP Example");
//construct the controls
txtBoxA = new TextField("UserName:", null, 50, TextField.ANY);
txtBoxB = new TextField("Password:", null, 50, TextField.ANY);
// result = new StringItem("Result:", null);
//add controls to the form
mainForm.append(txtBoxA);
mainForm.append(txtBoxB);
// mainForm.append(result);
//construct commands
cmdExit = new Command("Exit", Command.EXIT, 1);
cmdAdd = new Command("Add", Command.SCREEN, 1);
//add commands
mainForm.addCommand(cmdAdd);
mainForm.addCommand(cmdExit);
}
}
public void startApp() {
if (display == null) {
display = Display.getDisplay(this);
}
//display the main form
display.setCurrent(mainForm);
//register the command listener
mainForm.setCommandListener(this);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
if (c == cmdExit) {
this.destroyApp(false);
this.notifyDestroyed();
} else if (c == cmdAdd) {
//callWebServiceMethod();
Library lib=new Library();
lib.init();
}
}
my jar file coding is library.jar
public class Library {
String METHOD_NAME = "ValidateLogin_M";
String SOAP_ACTION ="http://64.244.69.235:81/MobileApp/ValidateLogin_M";
String NAMESPACE ="http://64.244.69.235:81/MobileApp/";
String URL ="http://64.244.69.235:81/MobileApp/service1.asmx";
public Library() {
// TODO Auto-generated constructor stub
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Library lib=new Library();
lib.init();
}
public void init()
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
String user= "gsrtestnew#gmail.com";
String password= "123456";
request.addProperty("UserID",user);
request.addProperty("Password",password);
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransport j2meHttpTransport = new HttpTransport(URL);
try {
j2meHttpTransport.call(SOAP_ACTION, envelope);
SoapObject content = (SoapObject) envelope.bodyIn;
String sum = content.getProperty(0).toString();
// result.setText(sum);
System.out.println("##########"+sum);
JSONArray jsonobj = new JSONArray(sum.toString());
System.out.println("Json obj length:: " + jsonobj.length());
if(jsonobj.length() == 0)
{
}
for(int i=0; i<jsonobj.length(); i++)
{
JSONObject jobj = jsonobj.getJSONObject(i);
String CustID = jobj.getString("CustID");
System.out.println("CustID is :: "+CustID);
String Email = jobj.getString("Email");
System.out.println("Email is :: "+Email);
String FirstName = jobj.getString("FirstName");
System.out.println("FirstName is :: "+FirstName);
String LastName = jobj.getString("LastName");
System.out.println("LastName is :: "+LastName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have imported the jar file and called as Library class. But still I am getting error.
My error is
Starting emulator in execution mode
Installing suite from: http://127.0.0.1:49412/WebApplication.jad
TRACE: <at java.lang.Error: ClassFormatError: 56>, Exception caught in Display class
java.lang.Error: ClassFormatError: 56
at com.web.application.Login.commandAction(Login.java:95)
at javax.microedition.lcdui.Display$ChameleonTunnel.callScreenListener(), bci=46
at com.sun.midp.chameleon.layers.SoftButtonLayer.processCommand(), bci=74
at com.sun.midp.chameleon.layers.SoftButtonLayer.commandSelected(), bci=11
at com.sun.midp.chameleon.layers.MenuLayer.pointerInput(), bci=170
at com.sun.midp.chameleon.CWindow.pointerInput(), bci=76
at javax.microedition.lcdui.Display$DisplayEventConsumerImpl.handlePointerEvent(), bci=19
at com.sun.midp.lcdui.DisplayEventListener.process(), bci=296
at com.sun.midp.events.EventQueue.run(), bci=179
at java.lang.Thread.run(Thread.java:722)
This has already been answered - jvm cannot load a class due to difference in version - cf - ClassFormatError: 56 while using hessian in j2me
Recompile with
javac -target 1.4 ...

Resources