Archived Forum Post

Index of archived forum posts

Question:

FTP .net 4.6 PutFileAsync Crash

Sep 16 '16 at 12:24

App c#.net 4.6 32bit ChilkatDotNet46.dll 32bit 9.5.0.58

I am running a series of PutFileAsync tasks, and waiting for the result from each to keep the UI responsive. I have disposed of the task after each call. In total I am processing about 1000 files.

After a random amount of files, usually between 20 – 30 the application crashes with the following error:

Problem signature:
Problem Event Name: APPCRASH
Application Name: WebUploader.exe
Application Version: 1.0.0.0
Application Timestamp: 577aaefe
Fault Module Name: ChilkatDotNet46.dll
Fault Module Version: 9.5.0.58
Fault Module Timestamp: 56e343a2
Exception Code: c0000005
Exception Offset: 00218c60
OS Version: 6.3.9600.2.0.0.256.48
Locale ID: 2057
Additional Information 1: 5861
Additional Information 2: 5861822e1919d7c014bbb064c64908b2
Additional Information 3: 02d8
Additional Information 4: 02d8506199fd4665cf321a24e7435238

Has anyone seen a similar issue and help resolve.

Thanks.


Answer

Thanks. If possible, please provide a snippet of code that shows exactly what to do in order to reproduce the problem. Also, if you are using callbacks (such as TaskCompleted or any other callback), realize that these callbacks occur in a background thread (not in the main UI thread). In that case, eliminate the callbacks to ensure that the crash is not caused by them.

If you post a sample detailing how to reproduce the problem, then I'll try to reproduce it myself. Typically, the only way to solve problems such as this is to be able to reproduce it..


Answer

PS> I will try to reproduce the problem by doing the obvious -- by starting many async PutFile tasks at once.

One note: If your program is trying to upload 1000 files all at once (simultaneously via async), it probably not a good idea to have too many trying to upload at once. (The crash should be fixed nonetheless, but even if fixed, I'm saying it's not of any benefit to have too many threads fighting for upload bandwidth.)

There are two possible improvements you can make:

1) The Chilkat.Global.MaxThreads property controls the maximum number of (Chilkat) thread pool threads. The default value is 100. The maximum value is 500. Note: Asynchronous worker threads are created on as needed up to the maximum. You might which to set this to a lower value.

Any Chilkat.Global property is such that it applies to all Chilkat objects. You may instantiate a Chilkat.Global object, set the property, and then discard it. If you instantiate another Chilkat.Global object, you'll see the property value set as you left it. In other words, the Chilkat.Global object is, under-the-covers, a singleton.

2) Use the Chilkat.TaskChain object to chain tasks so one executes after the other. Instead of having 1000 tasks all fighting each other, you could create N task chains, and then round-robin append each new task to a chain. Or your program could get more sophisticated and append each new task to the chain with the smallest number of tasks. Each task chain could be running one task after the other..


Answer

Below is some Pseudo code to show how I am using Chilkat in a proxy class, I have skipped some of the basic code for FTP login/disconnect etc. As the crash is random I cannot identify what part of the code is causing it and obviously cant retrieve the lastErrorText for the same reason.

private async MAIN(){

APPFTP cls_MyFTP = new APPFTP();
    APPFTP.ASyncTask ftp_Task;

//Open FTP connection

//Loop through 1000 files

//get local and remote path

//create new async putfile task and run
    bln_Success = cls_MyFTP.PutFileAsync(out ftp_Task, str_LocalPath, str_FTPFileName);

//if started ok then wait for it to complete
    if (bln_Success) 
        bln_Success = await FTP_TaskWait(obj_Token, ftp_Task);

//if task complete ok then get result of task
    if (bln_Success) 
        bln_Success = ftp_Task.GetResultBool;

ftp_Task.Dispose()

//show result
    if (bln_Success) 
        APPLOGS.Add("Sucsess!")
    else 
        APPLOGS.Add("Failed!")

//get next file

//close FTP connection

//Dispose of objects
}

private async Task<bool> FTP_TaskWait(CancellationToken CancelToken, APPFTP.ASyncTask FTPTask) {

while (FTPTask.Finished != true) {

//keep UI responsive
        try {
            await Task.Delay(25, CancelToken);
        } catch (TaskCanceledException) {

if (FTPTask != null)
                FTPTask.Cancel();

CancelToken.ThrowIfCancellationRequested();
        }
    }

return FTPTask.Success;
}

// below is part of FTP proxy class APPFTP
// ckTask is the ChilKat task object in the ASyncTask class which is in the 
// FTP proxy class APPFTP

class APPFTP : IDisposable {

public class ASyncTask {

public Chilkat.Task ckTask;

public bool Success
        {
            get
            {
                if (ckTask != null)
                    return ckTask.LastMethodSuccess;
                else
                    return false;
            }
        }

public bool GetResultBool
        {
            get
            {
                if (ckTask != null)
                    return ckTask.GetResultBool();
                else
                    return false;
            }
        }

public void Cancel() {
            if (ckTask != null)
                ckTask.Cancel();
        }

public void Dispose() {
            if (ckTask != null) {
                ckTask.ClearProgressLog();
                ckTask.Cancel();
                ckTask.Dispose();
                ckTask = null;
            }
        }

}

public bool PutFileAsync(out ASyncTask FTPTask, string LocalFile, string RemoteFile) {

FTPTask = new ASyncTask();
        FTPTask.ckTask = cls_FTP.PutFileAsync(LocalFile, RemoteFile);

if (FTPTask.ckTask == null)
            return false;

return FTPTask.ckTask.Run();
    }

}

Answer

Hang fire a bit, I have just gone back to my development machine and it is not crashing anymore, however if I run it on any production machines it still crashes.

I need to see if I can find some difference between them, I will keep you updated.


Answer

I think this requires a step back to explain the the Async functionality in Chilkat more clearly. The purpose of introducing the Chilkat.Task object and the Async functions is to provide a consistent async model across all programming languages on all platforms.

You would never use C#'s async/await WITH Chilkat's Async. You should use one or the other.

If you use C#'s async/await, then use it to wrap the synchronous Chilkat method. See this: http://www.chilkatforum.com/questions/11148/why-does-chilkat-implement-async-with-task-when-asyncawait-already-exists


Answer

I did find the cause of the crash which was the ckTask.Dispose() between each upload, however I have now re coded to use the native C# async framework instead of Chilkat and I will perform some tests and report back. I suspect I will no longer see the issue.