|
Hi ,
I have faced one issue on my project. One of our application is doing rename and Copy operation for tiff image from one location to another location in the server itself. I mean, in the Server D drive, copy the file from one directory to another directory.
The issue is:
Daily around thousands of images will be copied. Last week, One Tiff Image file length is differed from the original. The copied file has extra bytes. So the original and copied image size difference is 8bytes. I compared with WinMerge tool. Some bytes added at the end of the file.
Do you know the reason for this problem?. The server is Window 2008R2. Application build with .Net Framework 4.0.
|
|
|
|
|
cravi85 wrote: Do you know the reason for this problem? The first place I'd look is the source code of the application.
/ravi
|
|
|
|
|
This is the code file. I added onlymain thing. Other manipulations are confidential. So i am sorry for not able to give full code. But this part only related to file operation.
Major methods are ,
File.move , File.Copy.
This is Parellal Process. So i am using Parellal method.
The source code as below
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.Collections;
using System.Timers;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AccessSharedFiles
{
public partial class Parellal : Form
{
public Queue queBatch;
public System.Timers.Timer DurationForCopy;
public System.Timers.Timer DurationForProcess;
public bool currentlyProcessing = true;
public bool currentlyCopying = true;
public Parellal()
{
InitializeComponent();
}
private void Parellal_Load(object sender, EventArgs e)
{
try
{
queBatch = new Queue();
DurationForCopy = new System.Timers.Timer();
DurationForCopy.Interval = 5 * 1000;
DurationForCopy.Enabled = true;
DurationForCopy.Elapsed += new ElapsedEventHandler(CopyFiles);
DurationForProcess = new System.Timers.Timer();
DurationForProcess.Interval = 5 * 1000;
DurationForProcess.Enabled = true;
DurationForProcess.Elapsed += new ElapsedEventHandler(ProcessFiles);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void CopyFiles(object sender, EventArgs eArgs)
{
try
{
if (currentlyCopying)
{
currentlyCopying = false;
string[] files = Directory.GetFiles( @"C:\SDU\SDU_Parel\Source\");
foreach (string fi in files)
{
File.Move(fi, @"C:\SDU\SDU_Parel\Intermediate\" + fi.Split('\\')[fi.Split('\\').Length - 1].Split('.')[0] + ".tif");
PutFolderinQueue(fi.Split('\\')[fi.Split('\\').Length - 1].Split('.')[0] + ".tif");
break;
}
}
currentlyCopying = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
currentlyCopying = true;
}
}
private void PutFolderinQueue(string fileName)
{
try
{
string strVal = fileName.ToString();
Monitor.Enter(queBatch);
queBatch.Enqueue(fileName);
Monitor.Exit(queBatch);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ProcessFiles(object sender, EventArgs eArgs)
{
try
{
if (currentlyProcessing)
{
currentlyProcessing = false;
List<string> al = new List<string>();
Monitor.Enter(queBatch);
if (queBatch.Count > 0)
{
for (int intCount = 1; intCount <= queBatch.Count; intCount++)
al.Add(queBatch.Dequeue().ToString().Trim());
}
Monitor.Exit(queBatch);
Parallel.ForEach(al, name => { ProcessBatch(name); });
if (al != null)
{
al = null;
}
currentlyProcessing = true;
GC.Collect();
}
}
catch (Exception ex)
{
currentlyProcessing = true;
MessageBox.Show(ex.Message);
}
}
private void ProcessBatch(string ivalue)
{
try
{
File.Copy(@"C:\SDU\SDU_Parel\Intermediate\"+ivalue, @"C:\SDU\SDU_Parel\Destination\" + ivalue);
File.Delete(@"C:\SDU\SDU_Parel\Intermediate\" + ivalue);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
|
|
|
|
|
Some more information.
The above code will do as below:
Tiff Image File will be transferred continuously from one location to this server(Inside Source folder). My application will pick files from source folder for every 5 secs and move to Intermediate folder. After this file will be read by some confidential code. then this image file will be copied to Destination folder.
Last 1 year ,this process was working without any issue. But last week, TWO Image files had issue. These two file's size is greater than the original file.
The file 1:
Source folder: 1756 bytes
Destination folder : 1764 bytes
The file 2:
Source folder :26525 bytes
Destination Folder : 26529 bytes
I should not upload the tiff images because of some confidential code.
|
|
|
|
|
The right thing to do (IMHO) is to try to isolate the problem. I suggest writing a simple app that just copies one of the files. Use a hardcoded value for ivalue in the following fragment:
string ivalue = ...;
File.Copy(@"C:\SDU\SDU_Parel\Intermediate\"+ivalue, @"C:\SDU\SDU_Parel\Destination\" + ivalue);
File.Delete(@"C:\SDU\SDU_Parel\Intermediate\" + ivalue);
I honestly see no reason why the file sizes should be different. Are you sure you're examining the actual file length(s) and not the allocated sizes (which can differ based on sector size)? Wait, ignore that. Your source and destination devices are the same, and should have the same sector size.
/ravi
|
|
|
|
|
There's nothing here that should be changing file contents, unless there's a bug in File.Copy and I'd think that would have been found if it were the case (it must be one of the most commonly used Framework methods).
Does your application code open write streams on the intermediate file? I'd be pretty sure that your problem lies in there, almost certainly in a 'read, modify, write' byte array copy operation that doesn't check the read length properly.
|
|
|
|
|
Thanks for assisting me.
Intermediate code will do the some operation but last 1.5 years it was going fine.We recently added the Parallel.each concept instead of ordinary FOR LOOP for performance issue. So now this program utilize all the CPU core. I think , this area may be the cause.
But i tested with this code also. not helpful
|
|
|
|
|
This depends entirely on the code that is copying the files. Since you don't show that code, it's impossible to tell you what's going wrong.
|
|
|
|
|
please see the previous post. i have given my source code. thanks for your great assistance..
|
|
|
|
|
OK, the File.Copy method gets around to calling the CopyFile function in the Windows Kernel. It's telling Windows to copy the file. There is no .NET code that is doing the actual read and write operations.
The only thing I can think of is that you're copying the file before the buffer is flushed that is writing the file.
Gc.Collect()?? Remove it. You don't need it. All you're doing is screwing up the self-tuning portion of the garbage collector.
Honestly, this is the most complicated code I've seen for copying a batch of files. What are you doing with it all??
|
|
|
|
|
Thank you so much for you helping. I need to reproduce the issue. Is it possible? I tested many times and many ways but i couldnt.
This is for Financial purpose. Based on this image file, we will identify amount and all. This is outline only.Because i should not say about this confidential. Sorry for this.
Is there any way to reproduce this one? before flushing the file, how can we copy the file? Can you have the sample code?
|
|
|
|
|
How does this file show up? Is it being created by some other app? Is it being written by an FTP server? ...? ...? What?
The only way you can recreate the problem is if you replicate how the file is showing up.
A possible temporary solution to test with may be to wait about 30 seconds before you start copying the file.
|
|
|
|
|
I want yo show the screenshot for the problematic images compared with the original image. This comparision was made by WinMerge tool. From these screen shot, you can see the added bytes at the last. Please see the screenshot, it may give any idea to you.
but i dont know how to attach those screenshot in this ? can you assist me..
|
|
|
|
|
A screen shot will not help.
The part you have not described is where these files are coming from and are you waiting a for some amount of time before you try and queue the file up for copying?
|
|
|
|
|
i am using windowsform with C#. I want show data from database of ms access without sql. . . .!
|
|
|
|
|
|
Then you are probably looking for Linq to SQL , but I recommend SQL.
You'll never get very far if all you do is follow instructions.
|
|
|
|
|
PIEBALDconsult wrote: Then you are probably looking for Linq to SQL Can we expect any blogpost/article from you? Meanwhile....[^]
thatrajaCode converters | Education Needed
No thanks, I am all stocked up. - Luc Pattyn
When you're wrestling a gorilla, you don't stop when you're tired, you stop when the gorilla is - Henry Minute
|
|
|
|
|
Since Access runs entirely on SQL to manipulate the database, how else are you going to get the data out of it??
This sounds like an excuse for "I don't know SQL and don't want to learn it." Do yourself a favor and LEARN IT. You're not going to have a very good software development life without it.
|
|
|
|
|
<NoteToSelf>Create sockpuppets and upvote Dave's post a few more times.</NoteToSelf>
You'll never get very far if all you do is follow instructions.
|
|
|
|
|
|
Hi Everybody,
I want to use functions having callback in remoting mode.Summary of scenario is
1) I am having a shared class library which has a functions which contains callback
2)Server as standalone application which used to take session from shared class library
3)Client as standalone application which takes session from serer and then call the functions on it
Summary of my code is:
SharedLibrary:
namespace TestClassLibrary
{
public class Class1 : MarshalByRefObject
{
public delegate void NotifyCallback(string s);
public void SelectWithClassDialog(string msg, NotifyCallback callback, string title)
{
Console.WriteLine("SelectWithClassDialog");
Console.WriteLine(msg);
Console.WriteLine(title);
if (callback != null)
s_notify(callback);
}
}
public class TestSession : MarshalByRefObject
{
internal TestSession()
{
}
new internal void initialize()
{
_cls1 = new Class1();
}
private Class1 _cls1;
public Class1 Class1
{
get
{
return _cls1;
}
}
static private TestSession theSession;
public static TestSession GetSession()
{
lock (typeof(TestSession))
{
if (theSession == null)
{
theSession = new TestSession();
theSession.initialize();
}
}
return theSession;
}
} ServerCode:
namespace TestServer
{
class TestServer
{
static void Main()
{
Thread serverThread = new Thread(new ThreadStart(Run));
serverThread.Start();
}
public static void Run()
{
int port = 1234;
TestSession theSession = TestSession.GetSession();
LifetimeServices.LeaseTime = System.TimeSpan.FromDays(10000);
// Create a custom FormatterSinkProvider so that we can set its security type
// filter to Full. This is necessary for ObjectRefs to be deserialised
SoapServerFormatterSinkProvider provider = new SoapServerFormatterSinkProvider();
provider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilter Level.Full;
// Create the IDictionary to set the port on the channel instance.
IDictionary props = new Hashtable();
props["port"] = port;
// Create a new HTTP channel with the given provider and properties
HttpChannel channel = new HttpChannel(props, null, provider);
ChannelServices.RegisterChannel(channel, false);
// Export the Session object
RemotingServices.Marshal(theSession, "TestSession");
// Create the server object for clients to connect to
RemotingConfiguration.RegisterWellKnownServiceType (
typeof(ClientComms),
"RemoteServer",
WellKnownObjectMode.Singleton);
Thread.Sleep(Timeout.Infinite);
}
}
}
Client code:
namespace Client
{
class Program
{
private static TestSession theSession = null;
static TestClassLibrary.NotifyCallback ip = init_proc_body;
static void Main()
{
Console.WriteLine("Getting TestSession object...");
theSession = (TestSession)Activator.GetObject(typeof(TestSessio n), "http://localhost:1234/TestSession");
if (theSession == null)
{
Console.WriteLine("No Session object found. Exit.");
return;
}
Console.WriteLine("Got Session object");
theSession.Class1.SelectWithClassDialog("test", ip, "test_str"); // got exception here
}
public static void init_proc_body(String s)
{
Console.WriteLine("Inside callback");
Console.WriteLine(s);
}
}
}
In client I am trying to call function SelectWithClassDialog("test", ip, "test_str"); at this statement I will get an exception
System.Reflection.TargetInvocationException was unhandled
HResult=-2146232828
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
InnerException: System.IO.FileNotFoundException
HResult=-2147024894
Message=Could not load file or assembly 'Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
FileName=Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
If I run client program in non remoting then it works fine.(In non remoting mode I am directly taking session from shared lib in client application and then calling resp. function)
Also in remoting mode if I make call like SelectWithClassDialog("test", null, "test_str");
then it works fine.
So I think problem is with callback in remoting mode.
Can anybody help how to use SelectWithClassDialog("test", ip, "test_str"); in remoting mode with callback.
I am new to c# and stuck at this point,would appreciate any help.Thanks in advance.
|
|
|
|
|
|
Your problem is that you are binding the delegate to a method in a Client assembly class. That means that the code that tries to call it needs to know about that assembly, which is obviously bad.
In this situation when you're passing the delegate to a method which calls it directly, you can use an interface instead:
SharedAssembly:
interface IStringMessageRecipient {
void ProcessMessage(string s);
}
class Class1 {
public void SelectWithClassDialog(string msg, IStringMessageRecipient messageRecipient, string title) {
messageRecipient.ProcessMessage("did " + title);
}
Client:
class Client : IStringMessageRecipient {
IStringMessageRecipients.ProcessMessage(String s) {
Console.WriteLine("Inside callback");
Console.WriteLine(s);
}
}
PS please use <pre> tags for code blocks.
|
|
|
|
|
Thanks for the reply..
The approach of interface works but for that I need to open a port in client also.
HttpChannel channel = new HttpChannel(0);
ChannelServices.RegisterChannel(channel, false);
Now problem is that in actual scenario I have a c# wrapper over C.
So when in this case I used the Interface approach I got error like
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))
Can you please help me in fixing this problem.
|
|
|
|