Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

ADO.Net i BeginExecuteNonQuery problem

[es] :: .NET :: ADO.Net i BeginExecuteNonQuery problem

[ Pregleda: 1778 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

djoso

Član broj: 26879
Poruke: 34
*.bluenet.rs.



Profil

icon ADO.Net i BeginExecuteNonQuery problem11.02.2011. u 14:39 - pre 160 meseci
Imam problem sa AsyncCallback delegatom, sve verzije sam izprobao ali nista nece da upali. Evo primer koda i ostavicu sliku forme, pa neko ko zna da barata sa ovim da mi kaze gde gresim. Da se zna da sam sve verzije isprobao, sve codove koje sam nasao po netu. Jednostavno nece.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace WindowsFormsApplication9
{
public partial class BLOBSample : Form
{
private SqlConnection northwindConn = new SqlConnection("Data Source=.\\sqlexpress;" +
"Initial Catalog=Northwind;Integrated Security=True;Asynchronous processing=True");

private String completeFilePath = "";
private string savePath = "";

private bool isExecuting;

private void GetFilePath()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Select Document to Save";
ofd.ShowDialog();
completeFilePath = ofd.FileName;
}

private void GetSavePath()
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.Description = "Select a folder to restore BLOB file to";

fbd.ShowDialog();
savePath = fbd.SelectedPath;
}

// Create a table to hold our BLOB values.
private void CreateDocumentStorageTable()
{
SqlCommand createTabComm = new SqlCommand();
createTabComm.Connection = northwindConn;
createTabComm.CommandText =
"If OBJECT_ID('DocumentStorage') is not null " +
"DROP Table DocumentStorage " +
"Create Table DocumentStorage(" +
"DocumentID int Identity(1,1) not null, " +
"FileName nvarchar(255) not null, " +
"DocumentFile varbinary(max) not null)";

createTabComm.CommandType = CommandType.Text;

createTabComm.Connection.Open();
createTabComm.ExecuteNonQuery();
createTabComm.Connection.Close();
}

public BLOBSample()
{
InitializeComponent();
}

private void BLOBSample_Load(object sender, EventArgs e)
{
DialogResult response = MessageBox.Show(
"Create the Document Storage Table?" +
Environment.NewLine +
"Click Yes to create a new DocumentStorage table." +
"Click No if you already have one!",
"Create DocumentStorage table", MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);

switch (response)
{
case DialogResult.Yes:
CreateDocumentStorageTable();
break;
case DialogResult.No:
RefreshBobList();
break;
}
}

private void RefreshBobList()
{
comboBoxBlobList.Items.Clear();
SqlCommand execBlobComm = new SqlCommand(
"Select FileName from DocumentStorage", northwindConn);
SqlDataReader reader;

execBlobComm.Connection.Open();
reader = execBlobComm.ExecuteReader();
while (reader.Read())
{
comboBoxBlobList.Items.Add(reader[0]);
}
execBlobComm.Connection.Close();
try
{
comboBoxBlobList.SelectedIndex = 0;
}
catch (ArgumentOutOfRangeException aEx)
{
//
}
}

private void SaveBlobToDatabase()
{
// This call lets you select the
// binary file to save As a BLOB
// in the database.
GetFilePath();

// The BLOB holds the byte array to save.
byte[] BLOB;

// The FileStream is the stream of bytes
// that represent the binary file.
FileStream FileStream = new FileStream(completeFilePath, FileMode.Open, FileAccess.Read);

// The reader reads the binary data from the FileStream.
BinaryReader reader = new BinaryReader(FileStream);

// The BLOB is assigned the bytes from the reader.
// The file length is passed to the ReadBytes method
// telling it how many bytes to read.

FileInfo file = new FileInfo(completeFilePath);

BLOB = reader.ReadBytes((int)(file.Length));

FileStream.Close();
reader.Close();

// Create a command object to save
// the BLOB value.
SqlCommand SaveDocCommand = new SqlCommand();
SaveDocCommand.Connection = northwindConn;
SaveDocCommand.CommandText =
"Waitfor Delay '00:00:05';" +
"INSERT INTO DocumentStorage" +
"(FileName, DocumentFile)" +
"VALUES (@FileName, @DocumentFile)";

// Create parameters to store the filename and BLOB data.
SqlParameter FileNameParameter = new SqlParameter("@FileName", SqlDbType.NChar);
SqlParameter DocumentFileParameter = new SqlParameter("@DocumentFile", SqlDbType.Binary);
SaveDocCommand.Parameters.Add(FileNameParameter);
SaveDocCommand.Parameters.Add(DocumentFileParameter);

// Parse the filename out of the complete path
// and assign it to the parameter.
FileNameParameter.Value = completeFilePath.Substring(
completeFilePath.LastIndexOf("\\") + 1);

// Set the DocumentFile parameter to the BLOB Value.
DocumentFileParameter.Value = BLOB;

// Execute the command and save the BLOB to the database.
try
{
SaveDocCommand.Connection.Open();

PROBLEM JE OVDE, KADA PROSLEDIM AsyncCallback delegat jednostavno nece da se izvrsi operacija, inace dobro kada je sinhrono u pitanju. Pokusao sam i sa delegatom da invokujem glavni thread ali bez uspeha.


SaveDocCommand.ExecuteNonQuery(/*new AsyncCallback(Complete), SaveDocCommand*/);
MessageBox.Show(FileNameParameter.Value.ToString() + " saved to database.",
"BLOB Saved!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Save Failed", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
if (SaveDocCommand.Connection != null)
SaveDocCommand.Connection.Close();
}
}

private delegate void CrossThread(SqlCommand comm);
// ova metoda je proba za AsyncCallback
private void Complete(IAsyncResult itfAr)
{
SqlCommand comm = (SqlCommand)itfAr.AsyncState;
try
{
comm.EndExecuteNonQuery(itfAr);
//CrossThread ct = new CrossThread(FinishWork);
//this.Invoke(ct);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (comm.Connection != null)
comm.Connection.Close();
}
}


private void FetchBlobFromDatabase()
{
// Verify there is a BLOB selected to retrieve.
if (comboBoxBlobList.Text == "")
{
MessageBox.Show("Select a BLOB to fetch from the ComboBox");
return;
}

// Get the path to save the BLOB to.
GetSavePath();

// Create the Command object to fetch the selected BLOB.
SqlCommand GetBlobCommand = new SqlCommand(
"SELECT FileName, DocumentFile " +
"FROM DocumentStorage " +
"WHERE FileName = @DocName",
northwindConn);

GetBlobCommand.Parameters.Add(
"@DocName", SqlDbType.NVarChar).Value = comboBoxBlobList.Text;

// Current index to write the bytes to.
long CurrentIndex = 0;

// number of bytes to store in the BLOB.
int BufferSize = 100;

// Actual number of bytes returned when calling GetBytes.
long BytesReturned;

// The Byte array used to hold the buffer.
byte[] Blob = new byte[BufferSize];

GetBlobCommand.Connection.Open();

SqlDataReader reader =
GetBlobCommand.ExecuteReader(CommandBehavior.SequentialAccess);

while (reader.Read())
{
// Create or open the selected file.
FileStream FileStream = new FileStream(savePath + "\\" +
reader["FileName"].ToString(), FileMode.OpenOrCreate, FileAccess.Write);

// Set the writer to write the BLOB to the file.
BinaryWriter writer = new BinaryWriter(FileStream);

// Reset the index to the beginning of the file.
CurrentIndex = 0;

// Set the BytesReturned to the actual number
// of bytes returned by the GetBytes call.
BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0, BufferSize);

// If the BytesReturned fills the buffer keep appending to the file.
while (BytesReturned == BufferSize)
{
writer.Write(Blob);
writer.Flush();

CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0, BufferSize);
}

// When the BytesReturned no longer fills the buffer, write the remaining bytes.
writer.Write(Blob, 0, (int)(BytesReturned));
writer.Flush();

writer.Close();
FileStream.Close();
}
reader.Close();
GetBlobCommand.Connection.Close();
}

private void btnSaveBlob_Click(object sender, EventArgs e)
{
SaveBlobToDatabase();
}

private void btnRefreshList_Click(object sender, EventArgs e)
{
RefreshBobList();
}

private void btnFetchBlob_Click(object sender, EventArgs e)
{
FetchBlobFromDatabase();
}
}
}

Posto ne znam da li ovaj cod sme da bude ovde, hvala na savetu kako ga ostaviti. Inace ovo nije za projekat nego samo eksperimentalno zarad mog ucenja. Inace na formi imaju 3 button i 1 combobox. Ma nece pa nece, nije mi jasno ko pise codove koje ne mogu da se izvrse. Hvala na svakom savetu

NoSfArAtUs
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.25.*



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 08:49 - pre 160 meseci
Ne znam dje je greska, ali evo parce koda koji radi. Baza se ne kreira kao kod tebe, vec postoji (baza BLOB, tabela Dokumenti, polja Filename i Data):
Code:

            OpenFileDialog fd = new OpenFileDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                if (fd.FileName != string.Empty)
                {
                    System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder();

                    csb.DataSource = "VILLAIN\\SQLEXPRESS";
                    csb.InitialCatalog = "BLOB";
                    csb.UserID = "sa";
                    csb.Password = "pasword";
                    csb.PersistSecurityInfo = true; 
                    csb.AsynchronousProcessing = true;

                    System.IO.BinaryReader br = new System.IO.BinaryReader(new System.IO.FileStream(fd.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read));

                    byte[] data = br.ReadBytes((int)br.BaseStream.Length);

                    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
                    cmd.Connection = new System.Data.SqlClient.SqlConnection(csb.ConnectionString);
                    cmd.CommandText = "INSERT INTO Dokumenti (FileName, Data) VALUES (@FileName, @Data)";
                    cmd.Parameters.AddWithValue("FileName", fd.FileName);
                    cmd.Parameters.AddWithValue("Data", data);

                    cmd.Connection.Open();

                    cmd.BeginExecuteNonQuery(new AsyncCallback((IAsyncResult) => { MessageBox.Show("Gotovo!"); cmd.Connection.Close(); }), null);
                }
            }
 
Odgovor na temu

djoso

Član broj: 26879
Poruke: 34
*.bluenet.rs.



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 10:29 - pre 160 meseci
Probao sam bas to sto si mi ti ostavio, ali jednostavno kao da nece da se izvrsi do kraja, mislim nece da se izvrsi comm EndExecuteNonQuery. Komanda se izvrsava na 2 threadu to stoji, ali ne uspevam da vratim tu inf main threadu da je gotovo i da mi osvezi, tj. da kaze da je gotovo. Isprobao sam tvoju liniju koda za BeginExecuteNonQuery i nista.
NoSfArAtUs
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.25.*



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 11:01 - pre 160 meseci
EndExecuteNonQuery nije bas najbolji nacin, bar ja nikad ne kodistim Begin_NekiMetod i End_NekiMetod, vec CallBackove. EndExecuteNonQuery je jako spor, i bolje je koristiti samo ExecuteNonQuery.
Code:

cmd.BeginExecuteNonQuery(new AsyncCallback((IAsyncResult) => {MessageBox.Show("Gotovo!"); cmd.Connection.Close(); }), null);


Kada se zavrsi posao u bazi, sistem sam pozove funkciju koja je proslijedjena u BeginExecuteNonQuery:
Code:

(IAsyncResult) => {MessageBox.Show("Gotovo!"); cmd.Connection.Close(); }), 


Standardni CallBack, prihvata IAsyncResult parametar (koji, by the way, ne koristimo) i samo prikaze poruku i zatvori konekciju.

Ako moras da osvjezavas neke kontrole na pozivajucoj formi u CallBack-u, onda moras imati na umu da se CallBack izvrsava na drugom Threadu od Thread-a pozivajuce forme, pa, ako u njemu refereciras kontrole, onda moras te statement-e zamotati u jedan Invoke koji ces pozvati nad samom formom:

Code:

this.Invoke(new MethodInvoker(delegate{----- ovdje stavi to sto treba da uradis-----}));


tako da ce se kod u viticastim zagradama izvrsiti na Thread-u pozivajuce forme, i sve je ok. Ako opet zaglavis, javi :)
 
Odgovor na temu

djoso

Član broj: 26879
Poruke: 34
*.bluenet.rs.



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 13:17 - pre 160 meseci
Sve te razumem, to sam i pre toga isprobavao i cod koji si mi ti dao opet sam probao ali nece. Samo me interesuje jel si probao moj cod u kombinaciji sa tvojim u VS2008?? Posto dzaba mi kucas tu teoriju znam ali kompjuteri su izuzeteno glupe masine :D

Ako to radi kod tebe znaci mene nesto drugo zeza. Opet ti javljam da nece :))

Kada pokrenem app izvrsi se sve bez problema, ali comm se kao izvrssava u pozadini ali nista. KAda proverim u Sql browseru da li je fajl ucitan nista, nema ga. Ne znam sta je.

[Ovu poruku je menjao djoso dana 12.02.2011. u 14:32 GMT+1]
NoSfArAtUs
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.25.*



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 14:46 - pre 160 meseci
Evo ti kompletan ispravljen Solution.

Samo promijeni InitialCatalog u connection stringu
Prikačeni fajlovi
 
Odgovor na temu

djoso

Član broj: 26879
Poruke: 34
*.bluenet.rs.



Profil

icon Re: ADO.Net i BeginExecuteNonQuery problem12.02.2011. u 16:43 - pre 160 meseci
Ne mogu da verujem, radi. Da te pitam sto nije radilo na mom primeru, da li bi znao odgovor? :)
Kazem ja dzaba sve su to glupe masine. Prosto ne vidim razliku u codovima.
NoSfArAtUs
 
Odgovor na temu

[es] :: .NET :: ADO.Net i BeginExecuteNonQuery problem

[ Pregleda: 1778 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.