Thread i dzielenie się danymi

0

Mam problem z dzieleniem się danymi pomiędzy wątkiem głównym programu a utworzonym thread-em. Troszkę kodu :

[code]
private void FlashFrameMetod()
{
while (true)
{
while (Oblicz.CanWeWork(_rectangle1, TakeSRCIMage(), DSTImage))
{
using (var g = Graphics.FromImage(SRCImage))
{
var pen = new Pen(FrameColor, 2);
g.DrawRectangle(pen, _rectangle1);
}
Thread.Sleep(50);
}
}
}
[/code]

0

Z tego co piszesz wynika że masz problem z wątkami, ale nie napisałeś jaki, podałeś też kod jakiejś funkcji w której niewiedzę nic związanego z wątkami prócz funkcji Sleep, potrzeba więcej danych jeśli chcesz pomocy ;p

0

Metoda w 1-szym wątku działa jako Thread

W wątku głównym programu odwołuję się do właściwości SRCImage za pośrednictwem metody :
[code]
private Bitmap TakeSRCIMage ()
{

lock (zamek)
{
	if (SRCImage != null)
	{
		temp = SRCImage;
	}
	else
	{
		temp = null;
	}
}
return temp;

}
[/code]

Niestety podczas działania programu dostaję błąd

[code]
System.InvalidOperationException was unhandled
Message=Object is currently in use elsewhere.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.FromImage(Image image)
at Texturizer.Texturizer.FlashFrameMetod() in C:\Users\Owner\Dropbox\Texture Pack Mixer\MainForm.cs:line 324
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
[/code]

Jak się tego pozbyć ?

0
 private void FlashFrameMetod()
                {
                        while (true)
                        {
                                while (Oblicz.CanWeWork(_rectangle1, TakeSRCIMage(), DSTImage))
                                {
                                        using (var g = Graphics.FromImage(SRCImage))
                                                {
                                                        var pen = new Pen(FrameColor, 2);
                                                        g.DrawRectangle(pen, _rectangle1);
                                                }
                                                Thread.Sleep(50);
                                }
                        }
                }

Widzę że do funkcji Oblicz.CanWeWork pobierasz obrazek za pomocą TakeSRCIMage() ale kiedy tworzysz Graphics już używasz zmiennej, może to dlatego, po prostu zrób tak:

 private void FlashFrameMetod()
                {
                        while (true)
                        {
                                Bitmap b = null;
                                while (b = TakeSRCIMage() != null && Oblicz.CanWeWork(_rectangle1, b, DSTImage))
                                {
                                        using (var g = Graphics.FromImage(b))
                                                {
                                                        var pen = new Pen(FrameColor, 2);
                                                        g.DrawRectangle(pen, _rectangle1);
                                                }
                                                Thread.Sleep(50);
                                }
                        }
                }

Nie testowałem ale powinno działać, jednak jeśli dalej będzie wywalać ci ten błąd to zrób tak:

 private void FlashFrameMetod()
                {
                        while (true)
                        {
                                while (Oblicz.CanWeWork(_rectangle1, TakeSRCIMage(), DSTImage))
                                {
                                        using (var g = Graphics.FromImage(TakeSRCIMage()))
                                                {
                                                        var pen = new Pen(FrameColor, 2);
                                                        g.DrawRectangle(pen, _rectangle1);
                                                }
                                                Thread.Sleep(50);
                                }
                        }
                }
0

Niestety dalej trzepie wyjątkami. VS wskazuje na
[code]
using (var g = Graphics.FromImage(b))
[/code]

Wcześniej miałem wątku kod : ControlPaint.DrawReversibleFrame(_rectangle,Color.Black,FrameStyle.Dashed); i działało bez wyjątków ale gdy moja forma została zasłonięta inną ControlPaint rysował na innej formie ładny migający prostokącik :)

0

W takim razie gdzie w innym wątku program używa tej bitmapy?

0

w evencie wołanym po doubleclick na listboxie. Zmieniłem teraz podpięcie SrcPicBox.Image = new Bitmap(TakeSRCIMage()); i przestało walić wyjątkami. Sądziłem ,że ustawienie SRCImage = null zatrzyma wątek ale chyba za szybko wywołały się metody w wątku głównym i Thread nadal działał.
[code]
SRCImage = null;
DSTImage = null;
var srcPath = PathesListSRC.ElementAt(fileslistBox.SelectedIndex);
var dstPath = PathesListDST.ElementAt(fileslistBox.SelectedIndex);

SRCImage = new Bitmap(ioClass.LoadFile(srcPath));
SrcPicBox.Image = new Bitmap(TakeSRCIMage());
SrcPicBox.Size = ioClass.ScalePictureBox(TakeSRCIMage().Size);
DSTImage = ioClass.LoadFile(dstPath);
DstPicBox.Size = ioClass.ScalePictureBox(DSTImage.Size);

string selecteditemname = fileslistBox.SelectedItem.ToString();
Oblicz.Multipler = ioClass.FindMultilplierInXMLFile(selecteditemname);
_rectangle1 = Oblicz.ObliczRectangle(SrcPicBox.Size, TakeSRCIMage().Size, new Point(0, 0));
//RefreshForm();
[/code]

0

A czy mogł bym dodać Lock() do właściwości , do Get-era i Set-era np, tak :

private Bitmap _srcImage;
private Bitmap SRCImage
{
get
{
Bitmap bitmapa;
lock (zamek)
{
bitmapa = _srcImage;
}
return bitmapa;
}
set
{
lock (zamek)
{
_srcImage = value;
}
}
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1