D
D
DarkByte20152016-04-20 20:49:20
C++ / C#
DarkByte2015, 2016-04-20 20:49:20

Why does the server send a non-null object, while the client accepts null?

Help me please! Something strange is going on in my client-server application! In short, a task is sent from the server to the client, but it comes to the client as null. I've spent several days behind the debugger on this error... I put debug outputs wherever possible... I can't figure out how this happens. All tasks leave the server not null, this is 100%, but somehow they change to null in flight ... The most important thing is that the client accepts the first few tasks and they are not null, they are normally transferred. But at some point, times and null... Here is a link to a repository with a full project: https://github.com/DarkByte2015/CoursedWork_v5. I would be very grateful if someone can help.
The error falls in the Calculation function (on the client):

private async void Callback_GiveJobAsync(object sender, GiveJobEventArgs e)
{
    try
    {
        if (e.Job == null)
            Debug.WriteLine("null value received!");
 
        await Task.Run(() => Calculate(e.Job));
        Dispatch(() => Jobs.Add(e.Job));
        await Proxy.SetResultAsync(e.Job);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.StackTrace);
        Disconnect(null);
    }
}
 
private void Calculate(ClientJob job)
{
    try
    {
        Results = new ConcurrentBag<double>();
        var threadCount = Environment.ProcessorCount;
        var threadStep = (job.Top - job.Bottom) / threadCount;
        var threads = new List<Thread>();
        var x = job.Bottom;
 
        for (var i = 0; i < threadCount; i++, x += threadStep + job.Step)
        {
            var threadTask = new ClientJob()
            {
                Bottom = x,
                Top = x + threadStep,
                Step = job.Step,
                CpuLoading = job.CpuLoading
            };
 
            var thread = new Thread(ThreadHandler);
            threads.Add(thread);
            thread.Start(threadTask);
        }
 
        threads.ForEach(t => t.Join());
        job.Result = Results.Sum();
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.StackTrace);
    }
}

The Callback_GiveJobAsync function is attached to the callback event:
private void Connect(object param)
{
    try
    {                
        var callback = new ClientCallback();
        callback.GiveJob += Callback_GiveJobAsync;
        callback.ServerIsStopped += Callback_ServerIsStopped;
        var context = new InstanceContext(callback);
        Proxy = new JobServiceClient(context);
        Proxy.Endpoint.Address = new EndpointAddress($"net.tcp://{IP}:{Port}/JobService");
        Proxy.Connect();
        IsConnected = true;
    }
    catch (Exception e)
    {
        IsConnected = false;
        MessageBox.Show(e.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

public class ClientCallback : IJobServiceCallback
{
    public event EventHandler<GiveJobEventArgs> GiveJob;
 
    public event EventHandler ServerIsStopped;
 
    void IJobServiceCallback.OnGiveJob(ClientJob job) => GiveJob?.Invoke(this, new GiveJobEventArgs(job));
 
    void IJobServiceCallback.OnServerIsStopped() => ServerIsStopped?.Invoke(this, new EventArgs());
}

And so, spinning it higher and higher (calls), here is another function already on the server in which the desired object is actually passed (which is null sometimes):
public async void BeginCalculationAsync(ClientJob job)
{
    if (job == null)
        Debug.WriteLine("BeginCalculationAsync: job == null");
 
    Job = job;
    Job.CpuLoading = CpuLoading;
    _Returned = false;
    _Timer.Enabled = true;
    _Stopwatch.Start();
 
    Debug.WriteLine($"Job = {Job}; Job.Bottom = {Job.Bottom}; Job.Top = {Job.Top}; Job.Step = {Job.Step}; Job.Result = {Job.Result}; Job.CpuLoading = {Job.CpuLoading}");
 
    try
    {
        await Task.Run(() => Callback.OnGiveJob(Job));
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
        var args = new ClientAbortedEventArgs(e, Job);
        ClientAborted?.Invoke(this, args);
    }
}

Note specifically the output was made by condition if the task is null. So this conclusion never works. Therefore, there is no point in presenting the rest of the code. The task is lost...

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
DarkByte2015, 2016-04-21
@DarkByte2015

Problem solved.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question