Apex trigger Handler Test class - apex-trigger

I am writing the test class for Email trigger.As per the New frame work we modified the trigger and we created the handler class for that trigger.
All these Methods are Failed and I am getting these errors while running the test class.
System.NullPointerException: Attempt to de-reference a null object
Class.Email_TriggerHandler.getTriggerEvent: line 152, column 1
Class.Email_TriggerHandler.addToLoopCount: line 135, column 1
Class.Email_TriggerHandler.run: line 35, column 1
Class.Email_TriggerHandler_Test.testAfterDelete: line 56, column 1
#isTest
private class Email_TriggerHandler_Test {
private static final String TRIGGER_CONTEXT_ERROR = 'Trigger handler called outside of Trigger execution';
private static String lastMethodCalled;
private static Email_TriggerHandler_Test.TestHandler handler;
static {
handler = new Email_TriggerHandler_Test.TestHandler();
// override its internal trigger detection
handler.isTriggerExecuting = true;
}
/***************************************
* unit tests
***************************************/
// contexts tests
#isTest
static void testBeforeInsert() {
beforeInsertMode();
handler.run();
System.assertEquals('beforeInsert', lastMethodCalled, 'last method should be beforeInsert');
}
#isTest
static void testBeforeUpdate() {
beforeUpdateMode();
handler.run();
System.assertEquals('beforeUpdate', lastMethodCalled, 'last method should be beforeUpdate');
}
#isTest
static void testBeforeDelete() {
beforeDeleteMode();
handler.run();
System.assertEquals('beforeDelete', lastMethodCalled, 'last method should be beforeDelete');
}
#isTest
static void testAfterInsert() {
afterInsertMode();
handler.run();
System.assertEquals('afterInsert', lastMethodCalled, 'last method should be afterInsert');
}
#isTest
static void testAfterUpdate() {
afterUpdateMode();
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method should be afterUpdate');
}
#isTest
static void testAfterDelete() {
afterDeleteMode();
handler.run();
System.assertEquals('afterDelete', lastMethodCalled, 'last method should be afterDelete');
}
#isTest
static void testAfterUndelete() {
try{
afterUndeleteMode();
handler.run();
//System.assertEquals('afterUndelete', lastMethodCalled, 'last method should be afterUndelete');
}
catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assertEquals(TRIGGER_CONTEXT_ERROR, te.getMessage(), 'the exception message should match');
} catch(Exception e) {
//System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
#isTest
static void testNonTriggerContext() {
try{
handler.run();
System.assert(false, 'the handler ran but should have thrown');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assertEquals(TRIGGER_CONTEXT_ERROR, te.getMessage(), 'the exception message should match');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
// test bypass api
#isTest
static void testBypassAPI() {
afterUpdateMode();
// test a bypass and run handler
Email_TriggerHandler.bypass('TestHandler');
handler.run();
System.assertEquals(null, lastMethodCalled, 'last method should be null when bypassed');
System.assertEquals(true, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// clear that bypass and run handler
Email_TriggerHandler.clearBypass('TestHandler');
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method called should be afterUpdate');
System.assertEquals(false, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// test a re-bypass and run handler
Email_TriggerHandler.bypass('TestHandler');
handler.run();
System.assertEquals(null, lastMethodCalled, 'last method should be null when bypassed');
System.assertEquals(true, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// clear all bypasses and run handler
Email_TriggerHandler.clearAllBypasses();
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method called should be afterUpdate');
System.assertEquals(false, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
}
// instance method tests
#isTest
static void testLoopCount() {
beforeInsertMode();
// set the max loops to 2
handler.setMaxLoopCount(2);
// run the handler twice
handler.run();
handler.run();
// clear the tests
resetTest();
try {
// try running it. This should exceed the limit.
handler.run();
System.assert(false, 'the handler should throw on the 3rd run when maxloopcount is 3');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
// we're expecting to get here
System.assertEquals(null, lastMethodCalled, 'last method should be null');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
// clear the tests
resetTest();
// now clear the loop count
handler.clearMaxLoopCount();
try {
// re-run the handler. We shouldn't throw now.
handler.run();
System.assertEquals('beforeInsert', lastMethodCalled, 'last method should be beforeInsert');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assert(false, 'running the handler after clearing the loop count should not throw');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
#isTest
static void testLoopCountClass() {
Email_TriggerHandler.LoopCount lc = new Email_TriggerHandler.LoopCount();
System.assertEquals(5, lc.getMax(), 'max should be five on init');
System.assertEquals(0, lc.getCount(), 'count should be zero on init');
lc.increment();
System.assertEquals(1, lc.getCount(), 'count should be 1');
System.assertEquals(false, lc.exceeded(), 'should not be exceeded with count of 1');
lc.increment();
lc.increment();
lc.increment();
lc.increment();
System.assertEquals(5, lc.getCount(), 'count should be 5');
System.assertEquals(false, lc.exceeded(), 'should not be exceeded with count of 5');
lc.increment();
System.assertEquals(6, lc.getCount(), 'count should be 6');
System.assertEquals(true, lc.exceeded(), 'should not be exceeded with count of 6');
}
// private method tests
#isTest
static void testGetHandlerName() {
System.assertEquals('TestHandler', handler.getHandlerName(), 'handler name should match class name');
}
// test virtual methods
#isTest
static void testVirtualMethods() {
Email_TriggerHandler h = new Email_TriggerHandler();
h.beforeInsert();
h.beforeUpdate();
h.beforeDelete();
h.afterInsert();
h.afterUpdate();
h.afterDelete();
h.afterUndelete();
}
/***************************************
* testing utilities
***************************************/
private static void resetTest() {
lastMethodCalled = null;
}
// modes for testing
private static void beforeInsertMode() {
handler.setTriggerContext('before insert', true);
}
private static void beforeUpdateMode() {
handler.setTriggerContext('before update', true);
}
private static void beforeDeleteMode() {
handler.setTriggerContext('before delete', true);
}
private static void afterInsertMode() {
handler.setTriggerContext('after insert', true);
}
private static void afterUpdateMode() {
handler.setTriggerContext('after update', true);
}
private static void afterDeleteMode() {
handler.setTriggerContext('after delete', true);
}
private static void afterUndeleteMode() {
handler.setTriggerContext('after undelete', true);
}
// test implementation of the Email_TriggerHandler
private class TestHandler extends Email_TriggerHandler {
public override void beforeInsert() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeInsert';
}
public override void beforeUpdate() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeUpdate';
}
public override void beforeDelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeDelete';
}
public override void afterInsert() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterInsert';
}
public override void afterUpdate() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterUpdate';
}
public override void afterDelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterDelete';
}
public override void afterUndelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterUndelete';
}
}
}

Related

to invoke interface method 'retrofit2.Call on a null object reference

how can i solve null object while sending post request
error says
to invoke interface method 'retrofit2.Call com.itgrepnet.foodbundle.remote.UserService.addUser(com.itgrepnet.foodbundle.model.User)' on a null object reference
in AddUserActivity
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addNewUser();
}
private void addNewUser() {
User u = new User();
u.setFirstname(first_name.getText().toString());
u.setLastname(last_name.getText().toString());
u.setEmail(email.getText().toString());
u.setPassword(password.getText().toString());
Call<User> call = userService.addUser(u);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
Toast.makeText(getApplicationContext(), "User Created Successfully!", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Log.e("Error: ", t.getMessage());
}
});
}
});
UserService.java
#POST("user/")
Call<User> addUser(#Body User user);
RetrofitClient.java
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String url) {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}

Thread pipelining with RxJava

RxJava gurus, here is your chance to shine!
Can you ensure the following program does not throw an IllegalStateException by only changing the RxJava pipeline starting with Flowable.generate() in the main() method?
class ExportJob {
private static Scheduler singleThread(String threadName) {
return Schedulers.from(newFixedThreadPool(1, r -> {
Thread t = new Thread(r, threadName);
t.setDaemon(true);
return t;
}));
}
public static void main(String[] args) {
Scheduler genSched = singleThread("genThread");
Scheduler mapSched = singleThread("mapThread");
// execute on "genThread"
Flowable.generate(ExportJob::infiniteGenerator)
.subscribeOn(genSched, false)
// execute on "mapThread"
.observeOn(mapSched, false)
.concatMapMaybe(ExportJob::mapping)
// execute on the thread that creates the pipeline, block it until finished
.blockingForEach(ExportJob::terminal);
}
private static int nb;
/** Must execute on "genThread" thread. */
private static void infiniteGenerator(Emitter<Integer> emitter) {
print(nb, "infiniteGenerator");
emitter.onNext(nb++);
checkCurrentThread("genThread");
}
/** Must execute on "mapThread" thread. */
private static Maybe<Integer> mapping(Integer s) {
print(s, "mapping");
checkCurrentThread("mapThread");
return Maybe.just(s);
}
/** Must execute on "terminal" thread. */
private static void terminal(Integer s) {
print(s, "terminal");
checkCurrentThread("main");
}
private static void print(int item, String method) {
System.out.format("%d - %s - %s()%n", item, Thread.currentThread().getName(), method);
}
private static void checkCurrentThread(String expectedThreadName) throws IllegalStateException {
String name = Thread.currentThread().getName();
if (!name.equals(expectedThreadName)) {
throw new IllegalStateException("Thread changed from '" + expectedThreadName + "' to '" + name + "'");
}
}
}
You have to use subscribeOn(scheduler, true) so the requests are routed back to their expected threads as well:
Flowable.generate(ExportJob::infiniteGenerator)
.subscribeOn(genSched, true) // <------------------------------
// execute on "mapThread"
.observeOn(mapSched, false)
.concatMapMaybe(ExportJob::mapping)
.subscribeOn(mapSched, true) // <------------------------------
.blockingForEach(ExportJob::terminal);

javafx background tasks: call service in another service

I Would like to execute a background task which executes multiple background tasks. What i am actually trying to do is execute a background process which executes some code for every Object in a list, and does it within a fixed thread pool. So, for example, i have 100 users in the list and i am executing code for each of them concurrently but no more than 5 at the same time.
Therefore i am using two service/task pairs: One service/task for executing on the whole list of users, this service uses a fixed thread pool as its executor and executes a series of second service/task pairs for every user in the list.
like in the following example:
class MainService extends Service<List<User>> {
private List<User> users;
public MainService(List<User> users) { this.users=users; }
protected Task<List<User>> createTask(){
return new MainTask(this.users)
}
}
class Maintask extends Task<List<User>> {
private List<User> users;
private Executor executor;
public MainTask(List<User> users) {
this.users=users;
this.executor=Executors.newFixedThreadPool(5);
}
protected List<User> call() throws Exception {
for (User user : this.users) {
System.out.println("Starting single service");
SingleService service=new SingleService(user)
service.setExecutor(this.executor);
service.start();
System.out.println("Single service started");
}
}
}
class SingleService extends Service<User> {
private User user;
public SingleService(User user) { this.user=user; }
protected Task<User> createTask() {
return new SingleTask(this.user)
}
}
class SingleTask extends Task<User> {
private User user;
public SingleTask(User user) { this.user=user; }
protected User call() throws Exception() {
// Do some work
}
}
The code executes up to the moment when first "starting single service" is printed, the "single service started" message is not being printed at all. As far as i see the SingleService is started, but its createTask() is not being executed at all. Am i making some mistake here?
Well, I am trying to do the same thing, in different context... launch multiple services from a single main Service.
I've overridden all methods of Service, and this is my printout:
Service must only be used from the FX Application Thread {from onFailed() method}
Service does not run on FX thread, but can only be called from the FX thread.
Therefore, all Services and Tasks called within a Service or Task will not be executed.
This is my work around:
public class FXComponentImporter extends Service<Void> implements JarImporter {
//Scanner<T> = Service<List<Class<T>>>
private Scanner<Node> nodeScanner = null;
private Scanner<Paint> paintScanner = null;
private Scanner<Animation> animationScanner = null;
private static int nodeCount = 0, paintCount = 0, animationCount = 0;
private final ObservableMap<String, Class<?>> foundComponents = FXCollections.observableHashMap();
public FXComponentImporter() {
this(null);
}
public FXComponentImporter(File file) {
if (file != null) {
try {
this.nodeScanner = new Scanner<>(file, Node.class);
this.paintScanner = new Scanner<>(file, Paint.class);
this.animationScanner = new Scanner<>(file, Animation.class);
} catch (IOException ex) {
Logger.getLogger(FXComponentImporter.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
File f = importJar();
try {
this.nodeScanner = new Scanner<>(f, Node.class);
this.paintScanner = new Scanner<>(f, Paint.class);
this.animationScanner = new Scanner<>(f, Animation.class);
} catch (IOException ex) {
Logger.getLogger(FXComponentImporter.class.getName()).log(Level.SEVERE, null, ex);
}
}
this.scanningDone.bind(this.nodeScanningDone.and(this.paintScanningDone.and(this.animationScanningDone)));
this.scanningDone.addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
if(scanningDone.isBound()){
scanningDone.unbind();
}
start();
scanningDone.removeListener(this);
}
}
});
startScanning();
}
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
Map<String, Class<?>> map = new HashMap<>();
List<Class<Node>> nodes = new ArrayList<>();
List<Class<Paint>> paints = new ArrayList<>();
List<Class<Animation>> anims = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(1);
//Platform needed due to Service only accessed from FX thread
Platform.runLater(() -> {
try {
//FX Stuff done here
nodes.addAll(nodeScanner.getMatchingClasses());
paints.addAll(paintScanner.getMatchingClasses());
anims.addAll(animationScanner.getMatchingClasses());
} finally {
latch.countDown();
}
});
latch.await();
this.updateMessage("Scanning for Nodes ... ");
nodes.stream().forEach(n -> {
if(n != null){
map.putIfAbsent(n.getSimpleName(), n);
}
nodeCount++;
});
this.updateMessage("Found : " + nodeCount + " Nodes ... ");
this.updateMessage("Scanning for Paints ... ");
paints.stream().forEach(p -> {
if(p != null){
map.putIfAbsent(p.getSimpleName(), p);
}
paintCount++;
});
this.updateMessage("Found : " + paintCount + " Paints ... ");
this.updateMessage("Scanning for Animations ... ");
anims.stream().forEach(a -> {
if(a != null){
map.putIfAbsent(a.getSimpleName(), a);
}
animationCount++;
});
this.updateMessage("Found : " + animationCount + " Animations ... ");
foundComponents.putAll(map);
return null;
}
};
}
#Override
protected void executeTask(Task<Void> task) {
super.executeTask(task);
System.out.println(getClass().getSimpleName() + " is Executing " + task.getTitle());
}
#Override
protected void cancelled() {
super.cancelled();
System.out.println(getClass().getSimpleName() + " was Cancelled ... ");
}
#Override
protected void running() {
super.running();
System.out.println(getClass().getSimpleName() + " is Running ... ");
}
#Override
protected void ready() {
super.ready();
System.out.println(getClass().getSimpleName() + " is Ready! ... ");
}
#Override
protected void scheduled() {
super.scheduled();
System.out.println(getClass().getSimpleName() + " is Scheduled ... ");
}
#Override
protected void failed() {
super.failed();
System.out.println(getException().getMessage());
}
#Override
protected void succeeded() {
super.succeeded();
System.out.println("Importing Succeeded ... with: " + foundComponents.entrySet().size() + " results.\n");
foundComponents.forEach((s, c) -> {
System.out.println(c.getSuperclass().getSimpleName() + " >> " + s + " : " + c.getSimpleName());
});
}
#Override
public void restart() {
super.restart();
System.out.println(getClass().getSimpleName() + " is Restarting ... ");
}
private void startScanning() {
nodeScanner.stateProperty().addListener(nsl);
paintScanner.stateProperty().addListener(psl);
animationScanner.stateProperty().addListener(asl);
nodeScanner.start();
paintScanner.start();
animationScanner.start();
}
private final BooleanProperty scanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty nodeScanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty paintScanningDone = new SimpleBooleanProperty(false);
private final BooleanProperty animationScanningDone = new SimpleBooleanProperty(false);
private final ChangeListener nsl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
nodeScanningDone.set(true);
nodeScanner.stateProperty().removeListener(this);
}
}
};
private final ChangeListener psl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
paintScanningDone.set(true);
paintScanner.stateProperty().removeListener(this);
}
}
};
private final ChangeListener asl = new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
if (newValue.equals(State.SUCCEEDED)) {
animationScanningDone.set(true);
animationScanner.stateProperty().removeListener(this);
}
}
};
public ObservableMap<String, Class<?>> getFoundComponents() {
return foundComponents;
}
}
and my Interface if you wanna try it out:
public interface JarImporter {
public static File defaultDirectory = new File(System.getProperty("user.home"));
public static final FileChooser.ExtensionFilter classfilter = new FileChooser.ExtensionFilter("Jar files", "*.jar");
static FileChooser defaultFileChooser(){
FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(classfilter);
fc.setInitialDirectory(defaultDirectory);
return fc;
}
public default File importJar(){
File jar = defaultFileChooser().showOpenDialog(null);
if(jar != null){
return jar;
}else{
return null;
}
}
}
Hope this helps.. though just looked at Question date, and was a while ago...

InstantiationException while getLocation on Nokia device

New to Nokia development. I am trying to write a hello world for get GPS coordinates of my current location. What am I doing wrong here ?
public class HomeScreen extends MIDlet {
public HomeScreen() {
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
Displayable current = Display.getDisplay(this).getCurrent() ;
if (current == null) {
UpdateJourney updateJourney = new UpdateJourney(this) ;
Display.getDisplay(this).setCurrent(updateJourney) ;
}
}
}
public class UpdateJourney extends Form implements CommandListener, Runnable {
private LocationProvider myLocation;
private Criteria myCriteria;
private Location myCurrentLocation;
private HomeScreen helloScreen;
private Command exitCommand;
private Thread getLocationThread = new Thread(this);;
public UpdateJourney(HomeScreen helloScreen) {
super("Taxeeta");
StringItem helloText = new StringItem("", "Taxeeta");
super.append(helloText);
this.helloScreen = helloScreen;
getLocationThread.start();
}
public double getMyLatitude() {
return myCurrentLocation.getQualifiedCoordinates().getLatitude();
}
public double getMyLongitude() {
return myCurrentLocation.getQualifiedCoordinates().getLongitude();
}
public void commandAction(Command command, Displayable arg1) {
if (command == exitCommand) {
helloScreen.notifyDestroyed();
}
}
public void run() {
myCriteria = new Criteria();
myCriteria.setHorizontalAccuracy(500);
try {
myLocation = LocationProvider.getInstance(myCriteria);
myCurrentLocation = myLocation.getLocation(60);
} catch (LocationException e) {
e.printStackTrace();
System.out
.println("Error : Unable to initialize location provider");
return;
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("Error: Waited enough for location to return");
return;
}
System.out.println("Location returned Lat:"
+ myCurrentLocation.getQualifiedCoordinates().getLatitude()
+ " Lng:"
+ myCurrentLocation.getQualifiedCoordinates().getLongitude());
exitCommand = new Command("Location returned Lat:"
+ myCurrentLocation.getQualifiedCoordinates().getLatitude()
+ " Lng:"
+ myCurrentLocation.getQualifiedCoordinates().getLongitude(),
Command.EXIT, 1);
addCommand(exitCommand);
setCommandListener(this);
}
}
In the application descriptor I had UpdateJourney as the MIDlet, I changed it to HomeScreen and it worked.

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.

Resources