thread safety - Invoke: how can I assign UI obj from BackgroundWorker? C# -
here core of code. i've tried invoke every way china, same big red x , objectdisposed exception on form1. (edited out unrelated code brevity.)
using system; using system.globalization; using system.componentmodel; using system.collections.generic; using system.drawing; using system.io; using system.windows.forms; using knowncolorspalette; namespace color_visualizer { public partial class form1 : form { static cultureinfo m_culture = cultureinfo.currentculture; fastpixel m_fp; // fastpixel encapsulates // bitmap.lockbits() funcs & data private void backgroundworker1_dowork(object sender, system.componentmodel.doworkeventargs e) { double fangle, fradius, d; point3d vu, vv; point plocation = new point(); { m_pnormal = coord.plane.normal; fangle = math.atan2(m_pnormal.y, m_pnormal.x); fradius = math.sqrt(m_pnormal.x * m_pnormal.x + m_pnormal.y * m_pnormal.y); fangle += fspeed * 180 / math.pi; m_pnormal.x = math.cos(fangle) * fradius; m_pnormal.y = math.sin(fangle) * fradius; m_fp.lock(); m_fp.clear(color.black); foreach (foundcolors fc in m_lcolors.values) { vu = new point3d(coord.u); d = dist(fc.pt, ref vu); vv = coord.v; vv.mult(d); plocation.x = (int)(m_midhoriz + vu.norm()); plocation.y = (int)(m_midvert + vv.norm()); m_fp.setpixel(plocation, fc.color); } m_fp.unlock(); invoke((methodinvoker)delegate { picturebox1.image = m_fp.bitmap; }); } while (true); } public form1() { initializecomponent(); windowstate = formwindowstate.maximized; coordinatesystem.assignme(this); } void readcolors() // saved of wikipedia's 1200+ named colors { // text file. } private void form1_load(object sender, eventargs e) { readcolors(); point3d p = new point3d(127.5, 127.5, 127.5); foreach (foundcolors fc in m_lcolors.values) fc.pt = fc.color - p; // point3d class has // implicit operator casts , // color. coord = new coordinatesystem(new plane(new point3d(-127.5, -127.5, -127.5), new point3d(-1, 0, 0))); backgroundworker1.runworkerasync(); } double fspeed = 5; point3d m_pnormal = new point3d(); double m_fdist, m_fdot; public double dist(point3d pt, ref point3d vu) { double c1 = pt.dot(vu); double c2 = vu.dot(vu); double b = c1 / c2; vu.mult(b); //m_fdot = pt.dot(coord.normal); m_fdist = pt.norm(pt - vu); return m_fdist; } double m_midhoriz, m_midvert; private void form1_resize(object sender, eventargs e) { m_midhoriz = picturebox1.width / 2; m_midvert = picturebox1.height / 2; m_fp = new fastpixel(new bitmap(picturebox1.width, picturebox1.height)); } } }
this support code, not central question: sorting.cs
using system.collections.generic; using system.drawing; using system.diagnostics; using system.windows.forms; using knowncolorspalette; namespace color_visualizer { public partial class form1 : form { public static colorcomp m_compclr = new colorcomp(); public static namecomp m_compname = new namecomp(); sortedlist<color, foundcolors> m_lcolors = new sortedlist<color, foundcolors>(m_compclr); sortedlist<string, foundcolors> m_lcolorbyname = new sortedlist<string, foundcolors>(m_compname); [debuggerdisplayattribute("{name}, r={color.r}, g={color.g}, b={color.b}")] class foundcolors { public color color = color.empty; public string name = ""; public cielab_color clab; public point3d pt; public list<int> lclosest = new list<int>(); public int nfarthest; public foundcolors(foundcolors fc) { color = fc.color; name = fc.name; clab = new cielab_color(fc.clab.cie_l, fc.clab.cie_a, fc.clab.cie_b); lclosest.addrange(fc.lclosest); nfarthest = fc.nfarthest; } public foundcolors() { } } struct sort { public double dist; public int index; public sort(double _d, int _i) { dist = _d; index = _i; } } class distcomp : icomparer<sort> { int icomparer<sort>.compare(sort x, sort y) { if ((object)x == null) if ((object)y == null) return 0; else return -1; if ((object)y == null) return 1; if (x.dist > y.dist) return -1; return 1; } } public class namecomp : icomparer<string> { int icomparer<string>.compare(string x, string y) { if ((object)x == null) if ((object)y == null) return 0; else return -1; if ((object)y == null) return 1; return x.compareto(y); } } public class colorcomp : icomparer<color> { int icomparer<color>.compare(color x, color y) { if ((object)x == null) if ((object)y == null) return 0; else return -1; if ((object)y == null) return 1; if (x.r > y.r) return -1; else if (x.r < y.r) return 1; else if (x.g > y.g) return -1; else if (x.g < y.g) return 1; else if (x.b > y.b) return -1; else if (x.b < y.b) return 1; return 0; } } } }
and lastly more support code, coordinatesystem.cs:
using system; using system.drawing; using system.diagnostics; using system.windows.forms; namespace color_visualizer { public partial class form1 : form { class coordinatesystem { const int max = 256; const double planewidth = 600; static form1 me; static point3d axisz = new point3d(0, 0, 1); static point3d axisy = new point3d(0, 1, 0); private plane m_plane = new plane(new point3d(128, 128, 128), new point3d(-128, 0, 0)); private point3d m_pv = new point3d(0, 0, 0); private point3d m_pu = new point3d(0, 0, 0); private double m_finc; public coordinatesystem(plane axaxis) { m_finc = planewidth / me.clientsize.height; plane = axaxis; } public static void assignme(form1 form) { me = form; } public point3d u { { return m_pu; } protected set { m_pu = value; } } public point3d v { { return m_pv; } protected set { m_pv = value; } } public point3d normal { { return m_plane.normal; } set { m_plane.normal = value; } } static double coserror = 0.99619469809174553229501040247389; public plane plane { { return m_plane; } set { m_plane = value; if (m_plane.dot(axisz) > coserror) u = u.cross(m_plane, axisy); else u = u.cross(m_plane, axisz); u.div(u.norm()); v = u.cross(u, m_plane); v.div(v.norm()); } } } [debuggerdisplayattribute("x = {x}, y = {y}, z = {z}")] public class point3d { public double x, y, z; public point3d(double _x, double _y, double _z) { x = _x; y = _y; z = _z; } public point3d(point3d p) { x = p.x; y = p.y; z = p.z; } public point3d() { x = 0; y = 0; z = 0; } public bool equals(point3d p) { return x == p.x & y == p.y & z == p.z; } public override bool equals(object obj) { return equals((point3d)obj); } public static bool operator ==(point3d p1, point3d p2) { return p1.equals(p2); } public static bool operator !=(point3d p1, point3d p2) { return !p1.equals(p2); } public static point3d operator -(point3d e, point3d s) { return new point3d(e.x - s.x, e.y - s.y, e.z - s.z); } public static point3d operator +(point3d e, point3d s) { return new point3d(e.x + s.x, e.y + s.y, e.z + s.z); } public static point3d operator *(double m, point3d v) { return new point3d(m * v.x, m * v.y, m * v.z); } public static point3d operator *(point3d v, double m) { return new point3d(v.x / m, v.y / m, v.z / m); } public static point3d operator /(double m, point3d v) { return new point3d(m * v.x, m * v.y, m * v.z); } public static point3d operator /(point3d v, double m) { return new point3d(v.x / m, v.y / m, v.z / m); } public static implicit operator color(point3d p) { return color.fromargb((int)p.x, (int)p.y, (int)p.z); } public static implicit operator point3d(color c) { return new point3d(c.r, c.g, c.b); } //public override int gethashcode() //{ // unchecked // { // var hash = new spookyhash(); // hash.update(x); // hash.update(y); // hash.update(z); // return hash.final().gethashcode(); // } //} // dot product (3d) allows vector operations in arguments public double dot(point3d u, point3d v) { return u.x * v.x + u.y * v.y + u.z * v.z; } public double dot(point3d u) { return u.x * x + u.y * y + u.z * z; } public double norm(point3d v) { return math.sqrt(dot(v, v)); } // norm = length of vector public double norm() { return math.sqrt(dot(this, this)); } // norm = length of vector public double dist(point3d u, point3d v) { return norm(u - v); } // distance = norm of difference public double dist(point3d u) { return norm(this - u); } public point3d cross(point3d u, point3d v) { return new point3d(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x); } public point3d cross(point3d u) { return new point3d(u.y * z - u.z * y, u.z * x - u.x * z, u.x * y - u.y * x); } public void add(point3d p) { x += p.x; y += p.y; z += p.z; } public void mult(double m) { x *= m; y *= m; z *= m; } public void div(double m) { x /= m; y /= m; z /= m; } } class plane : point3d { point3d m_pnormal; public plane(point3d porigin, point3d pnormal) : base(porigin) { m_pnormal = pnormal; } public plane(point3d p) : base(p) { } public plane(double x, double y, double z) : base(x, y, z) { } public point3d normal { { return m_pnormal; } set { m_pnormal = value; } } public double pointtoplane(point3d p) { return p.dot(normal); } } private coordinatesystem m_coordsys; private coordinatesystem coord { { return m_coordsys; } set { m_coordsys = value; } } }
only 1st code segment genuinely relevant question, know ask it, included of supporting code.
note have tried such things diverse progresschanged event (after enabling in properties of course) , various forms of delegates. use simple matter old delegates, spent 10 hours today no success, , never fail find working code examples, if have wade thru dozens of inferior answers. there utter profusion of contradictory answers question depending on date of post , kind of approach suggested.
the invoke method work if thread.sleep() 200ms. haven't tested lower limit, won't consistent across machines, reporting won't informative.
Comments
Post a Comment