Accessing Current SharedPreferences Data from Background Services - android-studio

My app uses a countdown timer in the background in a class that extends Services. The background running service is designed to access the Sharedpreferences data of the app. During the countdown, a particular integer in the Sharedpreferences changes value and the updated value is expected to be accessed in the onFinish() call of the countdown timer. The problem now is that the Service don't read the updated valued from the Sharedpreferences but rather returns the initial value at the point the background service started.
I saw somewhere that the solution to the problem is to use
PreferenceManager.getDefaultSharedPreferences()
instead of getSharedPrefences to be able access the current SharedPreferences value. I implemented this recommendation but the problem persist.
Please somebody should help me out because trying to figure out this is taking too much of my time.
My code is here:
public class BroadcastService extends Service {
DatabaseHelperClass myDatabase = new DatabaseHelperClass(this);
private SharedPreferences defaultSharedPreferences, sharedPreferences, staffSignedIn;
private SharedPreferences.Editor staffEditor, defaultSharedPreferencesEditor;
int countSignIn;
private SimpleDateFormat simpleDateFormatII;
Long timeLeftInMiliseconds;
private final static String TAG = "BroadcastService";
public static final String COUNTDOWN_BR = "com.cenitscitech.www.etimebook.countdown_br";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
defaultSharedPreferencesEditor = defaultSharedPreferences.edit();
sharedPreferences = getSharedPreferences("setTime", MODE_PRIVATE);
//staffSignedIn = getSharedPreferences("present", MODE_PRIVATE);
//countSignIn = staffSignedIn.getInt("max", 0);
//staffEditor = staffSignedIn.edit();
simpleDateFormatII = new SimpleDateFormat("MMM EEE dd, yyyy HH:mm");
Log.i(TAG, "Starting timer in broadcast receiver...");
Log.i(TAG, "max Count Obtained onBroadcastCreate: "+defaultSharedPreferences.getInt("max", 0));
}
#Override
public void onDestroy() {
//cdt.cancel();
Log.i(TAG, "Timer in broadcast receiver cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timeLeftInMiliseconds = intent.getLongExtra("timeLeft", 0L);
cdt = new CountDownTimer(timeLeftInMiliseconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
SharedPreferences defaultShared = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
/*bi.putExtra("countdown", millisUntilFinished);
sendBroadcast(bi);*/
}
#Override
public void onFinish() {
SharedPreferences defaultSharedPreferences2 = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
countSignIn = defaultSharedPreferences2.getInt("max", 0);
Log.i(TAG, "Timer finished");
bi.putExtra("countdown", "Timer finished");
sendBroadcast(bi);
StringBuilder phoneBuilder = new StringBuilder();
Calendar cStart = Calendar.getInstance();
cStart.set(Calendar.HOUR_OF_DAY, 0);
cStart.set(Calendar.MINUTE, 0);
cStart.set(Calendar.SECOND, 0);
Long cStartLong = cStart.getTimeInMillis();
Calendar cEnd = Calendar.getInstance();
cEnd.set(Calendar.HOUR_OF_DAY, 23);
cEnd.set(Calendar.MINUTE, 59);
cEnd.set(Calendar.SECOND, 59);
Long cEndLong = cEnd.getTimeInMillis();
String[] conditionsElements;
Log.i(TAG + " onFinish", "MAXIMUM COUNT OBTAINED: " + defaultSharedPreferences2.getInt("max", 0));
Log.i(TAG + " onFinish", "MAXIMUM COUNT OBTAINED: " + countSignIn);
if (defaultSharedPreferences2.getInt("max", 0) > 0) {
Log.i(TAG + " onFinish", "CURRENT countSignIn Value: "+countSignIn+"\n"+" max Value: "+defaultSharedPreferences2.getInt("max", 0));
conditionsElements = new String[defaultSharedPreferences2.getInt("max", 0)];
for (int i = 1; i <= defaultSharedPreferences2.getInt("max", 0); i++) {
conditionsElements[i - 1] = defaultSharedPreferences2.getString(Integer.toString(i), "NoElement");
Log.i(TAG + " onFinish", "conditionsElement[" + (i - 1) + "] = " + defaultSharedPreferences2.getString(Integer.toString(i), "NoElement"));
if (i < defaultSharedPreferences2.getInt("max", 0)) {
phoneBuilder.append("MOBILE_NUMBER = ? OR ");
Log.i(TAG + " onFinish", "phoneBuilder[" + (i - 1) + "]: " + phoneBuilder);
//phoneBuilder.append(staffSignedIn.getString(Integer.toString(i), "NoStaff")+"_");
} else if (i == defaultSharedPreferences2.getInt("max", 0)) {
//phoneBuilder.append(staffSignedIn.getString(Integer.toString(i), "NoStaff"));
phoneBuilder.append("MOBILE_NUMBER = ?");
Log.i(TAG + " onFinish", "phoneBuilder[final]: " + phoneBuilder);
}
}
} else {
Log.i(TAG + " onFinishInsideElse", "CURRENT countSignIn Value: "+countSignIn+"\n"+" max Value: "+defaultSharedPreferences2.getInt("max", 0));
conditionsElements = new String[1];
conditionsElements[0] = "NoElement";
phoneBuilder.append("MOBILE_NUMBER = ?");
}
Cursor cursor = myDatabase.queryAbsentStaff(SURNAME_COLUMN + ", " + FIRST_NAME_COLUMN + ", " + MIDDLE_NAME_COLUMN + ", " + MOBILE_NUMBER_COLUMN + ", " + DATE_COLUMN,
SURNAME_COLUMN + ", " + FIRST_NAME_COLUMN + ", " + MIDDLE_NAME_COLUMN + ", " + MOBILE_NUMBER_COLUMN + ", " + DATE_COLUMN,
phoneBuilder.toString(),
conditionsElements);
Log.i(TAG + " onFinish", "\n" + "SET TIMES:" + "\n" + cStartLong + "\n" + cEndLong + "\n" + "RETURNED ROWS:" + "\n" + cursor.getCount());
/*staffEditor.putInt("max", 0);
staffEditor.apply();
for(int i=0; i<staffSignedIn.getInt("totalStaff", 100); i++){
staffEditor.putString(Integer.toString((i+1)), "empty").apply();
}*/
if(cursor.moveToFirst()){
for (int i = 0; i < cursor.getCount(); i++) {
if(myDatabase.insertTimeBookRecord(cursor.getString(cursor.getColumnIndex(SURNAME_COLUMN)), cursor.getString(cursor.getColumnIndex(FIRST_NAME_COLUMN)),
cursor.getString(cursor.getColumnIndex(MIDDLE_NAME_COLUMN)), cursor.getString(cursor.getColumnIndex(MOBILE_NUMBER_COLUMN)),
"ABSENT", Long.toString(System.currentTimeMillis()), 1000000L, "NO", "0000", System.currentTimeMillis(), "notSynced", "notSynced")){
cursor.moveToNext();
if(cursor.isAfterLast()){
cursor.close();
}
}else{
cursor.moveToNext();
if(cursor.isAfterLast()){
cursor.close();
}
}
}
}
Log.i(TAG +" onFinish: ", "max val reset: "+defaultSharedPreferences2.getInt("max", 0));

Related

I have this array class that is not removing items after re-running my recyclerview

The below class is used in an array.
package com.example.ShivitoMGO;
public class RoomTable {
public String RoomName,UpDown,minmaxint;
}
Main Activity
static ArrayList <RoomTable> CountCheck = new ArrayList<>();
public void playerup(View vvv){
st_spinner = v1.findViewById(R.id.spinner);
st_reportLayout = v1.findViewById(R.id.reportlayout);
st_Leanervidimg = v1.findViewById(R.id.Linearvidcopy);
TextView roomname = v1.findViewById(R.id.action_Players1);
RoomTable roomtb = new RoomTable();
if (CountCheck.size() == 0){
//playerupdown = "up";
Toast.makeText(this, "Will notify when " + mRooms.get(position1) + " players increase #" + mRoomSize.get(position1), Toast.LENGTH_LONG).show();
String[] minmaxval = mRoomSize.get(position1).split("/");
CountCheckint = Integer.parseInt(minmaxval[0].trim());
//CountCheck = (String) mRooms.get(position1);
roomtb.RoomName = (String) mRooms.get(position1);
roomtb.minmaxint = minmaxval[0].trim();
roomtb.UpDown = "up";
Log.d("added: ", "it was added");
CountCheck.add(roomtb);
Log.d("RoomTableadd: ",roomtb.RoomName+ " " + roomtb.minmaxint +" " +roomtb.UpDown);
st_reportLayout.setVisibility(View.GONE);
Log.d("Longclickhere: ", mRoomSize.get(position1));
Log.d("RoomNameCount ", String.valueOf(CountCheck.get(0).RoomName));
}else {
int exist1 = 0;
int poss;
for (int i = 0; i < CountCheck.size(); i++) {
if (roomname.getText() == CountCheck.get(i).RoomName) {
Log.d("RoomNametxt: " , CountCheck.get(i).RoomName);
Log.d("RoomNametxt: ", (String) roomname.getText());
Toast.makeText(this, "Notification " + CountCheck.get(i).RoomName + " OFF!", Toast.LENGTH_LONG).show();
Log.d("Removed item: ", String.valueOf(CountCheck.size()));
CountCheck.remove(i);
Log.d("Removed item: ", String.valueOf(CountCheck.size()));
st_reportLayout.setVisibility(View.GONE);
exist1 = 1;
poss = i;
} else {
exist1 = 0;
}
}
if (exist1 == 0) {
Toast.makeText(this, "Will notify when " + mRooms.get(position1) + " players increase #" + mRoomSize.get(position1), Toast.LENGTH_LONG).show();
String[] minmaxval = mRoomSize.get(position1).split("/");
CountCheckint = Integer.parseInt(minmaxval[0].trim());
//CountCheck = (String) mRooms.get(position1);
roomtb.RoomName = (String) mRooms.get(position1);
roomtb.minmaxint = minmaxval[0].trim();
roomtb.UpDown = "up";
Log.d("added: ", "it was added");
CountCheck.add(roomtb);
Log.d("RoomTableadd: ", roomtb.RoomName + " " + roomtb.minmaxint + " " + roomtb.UpDown);
st_reportLayout.setVisibility(View.GONE);
}
Log.d("CountSize: ", String.valueOf(CountCheck.size()));
for (int xb = 0;xb<CountCheck.size();xb++) {
try {
Log.d("RoomNameCount ", String.valueOf(CountCheck.get(xb).RoomName));
} catch (Exception e) {
Log.d("Out of range ", String.valueOf(e));
}
}
}
}
Recycler-View
#Override
public boolean onLongClick(View v) {
// Launch your web intent
if (CountCheck.size() != 0){
Log.d("Longclickhere: ",mRoomSize.get(position));
Toast.makeText(mContext, mRoomSize.get(position), Toast.LENGTH_SHORT).show();
Toast.makeText(mContext, "Will notify when "+mRooms.get(position)+" players decrease", Toast.LENGTH_SHORT).show();
String[] minmaxval = mRoomSize.get(position).split("/");
MainActivity.CountCheckint = Integer.parseInt(minmaxval[0].trim());
} else{
//MainActivity.CountCheck = "";
Toast.makeText(mContext, "Player Decrease notification OFF", Toast.LENGTH_SHORT).show();
}
return true;
In this app the recycler view creates the "rooms" and if the room is selected the textview and 2 other values are put in to the RoomTable. these are stored and used in a service to check if ether of the other to values change. Everything works as intended unless i use the swip-to-refresh witch runs the recycler-view again. If i do not refresh and i select the same item in the recycler-view it will remove it from CountCheck . However if i run the refresh and select the same recycler-view item that i selected previously it will add it instead of removing it. This Makes no since to me because i use a for loop to Check the CountCheck.get(i).RoomName aka the textview and if the names are the same then my if statement will remove instead of add. is it somehow possible i'm ending up with 2 CountCheck Objects????? with the same name???? Please I'm out of ideas on this one. Thanks.
I dont remember why. Maybe someone can explain but i changed this line
if (roomname.getText() == CountCheck.get(i).RoomName)
To this
if (roomname.getText().equals(CountCheck.get(i).RoomName));
and that fixed the issue. please let me know the difference if you are reading this.

Changing the constraints in a Container object

In Java 8, the Container class has an void add(Component comp, Object constraints) method that adds the component with a constraints information. I want to build a GUI with three panels, where pressing a button would result in switching the constraint information of the components that do not include the button object. How is it possible to switch the constraint information?
EDIT:
I tried the following:
private Map<SpecUITitlePanel, GridBagConstraints> constraints = new Hashtable<SpecUITitlePanel, GridBagConstraints>();
[…]
switchPanelsButton.setText( "Switch panels");
switchPanelsButton.addActionListener( new java.awt.event.ActionListener() {
public void actionPerformed( final java.awt.event.ActionEvent event) {
switchPanelsActionPerformed( event);
}
[…]
private void switchPanelsActionPerformed( final java.awt.event.ActionEvent event) {
boolean swapped = false;
final GridBagLayout layout = (GridBagLayout) getLayout();
final Iterator<SpecUITitlePanel> keysIter = constraints.keySet().iterator();
// summaryPanel, testPanel
while (keysIter.hasNext() && layout != null) {
final SpecUITitlePanel key = keysIter.next();
final String title = key.getTitle();
final Iterator<SpecUITitlePanel> keysIter2 = constraints.keySet().iterator();
while (keysIter2.hasNext()) {
final SpecUITitlePanel key2 = keysIter2.next();
final String title2 = key2.getTitle();
if (!title.equals( title2)) {
if (!title.contains( BUTTON_PANEL_TITLE) && !title2.contains( BUTTON_PANEL_TITLE)) {
// swap components
String message = "component = " + title + ", "
+ constraints.get( key) + "; component2 = " + title2
+ ", " + constraints.get( key2);
System.out.println( message);
final GridBagConstraints value = constraints.get( key);
final GridBagConstraints value2 = constraints.get( key2);
constraints.put(key, value2);
layout.setConstraints( key, value2);
constraints.put(key2, value);
layout.setConstraints( key2, value);
swapped = true;
message = "component = " + title + ", "
+ constraints.get( key) + "; component2 = " + title2
+ ", " + constraints.get( key2);
System.out.println( message);
}
}
}
}
if (swapped) {
repaint();
}
}
The relevant part of the output is
component = Test, java.awt.GridBagConstraints#5179288b; component2 = tna.rads.main_panel.violation_summary_panel, java.awt.GridBagConstraints#f1a7ed2
component = Test, java.awt.GridBagConstraints#f1a7ed2; component2 = tna.rads.main_panel.violation_summary_panel, java.awt.GridBagConstraints#5179288b

How can opencv image processing run faster?

I am working on android studio with OpenCV library. I am dealing with ColorBlobDetectionActivity class so I want to rearrenge its processing. OpenCV processes all screen but I want to process just particular region to make it faster on android camera.Can someone help me?
Here it is ColorBlobDetectionActivity Class Code:
private boolean mIsColorSelected = false;
private Mat mRgba;
private Scalar mBlobColorRgba;
private Scalar mBlobColorHsv;
private ColorBlobDetector mDetector;
private Mat mSpectrum;
private Size SPECTRUM_SIZE;
private Scalar CONTOUR_COLOR;
private CameraBridgeViewBase mOpenCvCameraView;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public ColorBlobDetectionActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.color_blob_detection_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mDetector = new ColorBlobDetector();
mSpectrum = new Mat();
mBlobColorRgba = new Scalar(255);
mBlobColorHsv = new Scalar(255);
SPECTRUM_SIZE = new Size(200, 64);
CONTOUR_COLOR = new Scalar(255,0,0,255);
}
public void onCameraViewStopped() {
mRgba.release();
}
public boolean onTouch(View v, MotionEvent event) {
int cols = mRgba.cols();
int rows = mRgba.rows();
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
Rect touchedRect = new Rect();
touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
Mat touchedRegionRgba = mRgba.submat(touchedRect);
Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
// Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
int pointCount = touchedRect.width*touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++)
mBlobColorHsv.val[i] /= pointCount;
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
mIsColorSelected = true;
touchedRegionRgba.release();
touchedRegionHsv.release();
return false; // don't need subsequent touch events
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
if (mIsColorSelected) {
mDetector.process(mRgba);
List<MatOfPoint> contours = mDetector.getContours();
Log.e(TAG, "Contours count: " + contours.size());
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
Mat colorLabel = mRgba.submat(4, 68, 4, 68);
colorLabel.setTo(mBlobColorRgba);
Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols());
mSpectrum.copyTo(spectrumLabel);
}
return mRgba;
}
private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
Mat pointMatRgba = new Mat();
Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
return new Scalar(pointMatRgba.get(0, 0));
}
}

Use of dbms_lock inconsistent using jdbc

Why does the protected Java code execute in more then one thread at a time?
Thread-1 - protected code iteration 0
Thread-0 - protected code iteration 0
Thread-1 - protected code iteration 1
Thread-0 - protected code iteration 1
Thread-0 - protected code iteration 2
Thread-1 - protected code iteration 2
Thread-1 - protected code iteration 3
Thread-0 - protected code iteration 3
Run it enough times it can execute as expected.
public class DbmsLockTest implements Runnable {
Connection con; String key; int timeout;
public DbmsLockTest(Connection con, String key, int timeout) {
this.con = con; this.key = key; this.timeout = timeout;
}
public static void log(String str) {
System.out.println(new Date() + " - "
+ Thread.currentThread().getName() + " - " + str);
}
#Override
public void run() {
lockKey(con, key, timeout);
}
public static void lockKey(Connection con, String key, int timeout) {
log("start lockKey " + " key: " + key);
CallableStatement cStmt = null;
int rc = 0;
try {
StringBuilder sql = new StringBuilder(500);
sql.append("DECLARE");
sql.append(" v_lockhandle VARCHAR2(200);");
sql.append("BEGIN");
sql.append(" dbms_lock.allocate_unique(lockname => ?, lockhandle => v_lockhandle);");
sql.append(" ? := dbms_lock.request(lockhandle => v_lockhandle, lockmode => 6,");
sql.append(" timeout => ?, release_on_commit =>true);");
sql.append(" ? := v_lockhandle;");
sql.append("END;");
String lockKey = "LockKey-" + key;
cStmt = con.prepareCall(sql.toString());
cStmt.setString(1, lockKey);
cStmt.registerOutParameter(2, Types.NUMERIC);
cStmt.setInt(3, timeout);
cStmt.registerOutParameter(4, Types.VARCHAR);
log("executeUpdate start: " + lockKey + "] ");
cStmt.executeUpdate();
log("executeUpdate end: " + lockKey + "] ");
rc = cStmt.getInt(2);
log("return value from request=[" + rc + "] ");
if (rc != 0) {
System.out.println("6001 lock obtained: "
+ Thread.currentThread().getName());
throw new RuntimeException("lock acquisition failed with code=" + rc);
}
log("v_lockhandle=[" + cStmt.getString(4) + "] ");
for (int i = 0; i < 4; i++) {
try {
Thread.sleep(1000 * 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
log("***** protected code iteration ***** " + i);
}
con.commit();
} catch (SQLException e) {
log("int timeout: " + Thread.currentThread().getName());
throw new RuntimeException("SQLException locking balance for user "
+ key, e);
} finally {
try {
if (cStmt != null) {
cStmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
log("Exiting=[" + rc + "] ");
}
public static void main(String[] args) throws Exception {
new oracle.jdbc.OracleDriver();
List<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 2; i++) {
Connection connection = DriverManager
.getConnection("jdbc:oracle:thin:#localhost:1521:xe",
"<username>", "password");
Thread t = new Thread(new DbmsLockTest(connection, "mykey", 10));
list.add(t);
}
for (Thread t : list) {
t.start();
}
}
}

Strange behavior of threads

I’m writing an application that communicates with some hardware using the MODBUS protocol.
I'm using this sample from Code Project.
While trying to optimize the code (mainly the PollFunction function), I've encountered with a very strange threads lock.
Instead of sending each line of string to the DoGUIUpdate delagate, I'm constructing a string array and sending it as a whole.
Doing so causes the application to crush with a System.Reflection.targetParametercountException: Parameter count mismatch error.
The original code:
public delegate void GUIUpdate(string paramString);
public void DoGUIUpdate(string paramString)
{
if (InvokeRequired)
BeginInvoke(new GUIUpdate(DoGUIUpdate), paramString);
else
lstRegisterValues.Items.Add(paramString);
}
private void PollFunction()
{
...
string itemString;
for (int i = 0; i < pollLength; i++)
{
itemString = "[" + Convert.ToString(pollStart + i + 40001) + "] , MB[" + Convert.ToString(pollStart + i) + "] = " + values[i];
DoGUIUpdate(itemString);
}
}
My code:
public delegate void GUIUpdate2(string[] paramString);
public void DoGUIUpdate2(string[] paramString)
{
if (InvokeRequired)
BeginInvoke(new GUIUpdate2(DoGUIUpdate2), paramString);
else
{
lstRegisterValues.Items.Clear();
lstRegisterValues.Items.AddRange(paramString);
}
}
string[] valuesStrings;
private void PollFunction()
{
...
valuesStrings = new string[pollLength];
for (int i = 0; i < pollLength; i++)
{
valuesStrings[i] = "[" + Convert.ToString(pollStart + i + 40001) + "] , MB[" + Convert.ToString(pollStart + i) + "] = " + values[i];
}
DoGUIUpdate2(valuesStrings);
}
Any advice will be welcome.
i think BeginInvoke(new GUIUpdate2(DoGUIUpdate2), paramString); is the problem...
the second parameter of "begininvoke" accepts a param object[] params which will result in the call DoGuiUpdate(string1,string2,string3) which is not what you want...
try encapsulate in the following way:
BeginInvoke(new GUIUpdate2(DoGUIUpdate2), new[]{ paramString });

Resources