如何在异步方法中使用其他类中的其他函数

时间:2015-03-25 12:25:15

标签: c# wpf multithreading

我对Asynchronous很新,我理解一些一般概念,但我似乎无法解决几个问题。

我有以下ReceiveCallback:

public static void ReceiveCallback(IAsyncResult AR)
    {
        Socket CurrentSocket = (Socket)AR.AsyncState;
        int DataReceived = 0;

        try
        {
            DataReceived = CurrentSocket.EndReceive(AR);
        }
        catch (SocketException)
        {
            CurrentSocket.Close();
            return;
        }

        byte[] receivedBuffer = new byte[DataReceived];
        Array.Copy(Buffer, receivedBuffer, DataReceived);
        strReceived = Encoding.ASCII.GetString(receivedBuffer); // We are saving the latest receivedBuffer in a string.
        new MainWindow().Process(); // We are accessing a function in the MainWindow class
        receiveDone.Set();
        CurrentSocket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, CurrentSocket);
    }

这是“Process()”代码:

public void Process()
    {
         lblReceived.Text = ClientSocket.strReceived; // Trying to set what we received in a label..
    }
  1. 在线:“new MainWindow()。Process();”, 我收到以下异常:“附加信息:调用线程必须是STA,因为许多UI组件都需要这个。” 我已经搜索过,并理解为什么它给了我例外,但是有些代码对我不起作用。

  2. 标签没有改变,我知道我正在创建一个MainWindow的新实例,这就是为什么没有显示,但我正在寻找如何通过使用新实例来改变标签的例子

1 个答案:

答案 0 :(得分:0)

不幸的是,如果没有a good, minimal, complete code example,就无法了解有关您问题的足够背景信息,无法提供准确答案。

但可以做一些一般性的观察:

  1. 最重要的是,如果你需要访问一个类的实例成员,那是因为(或者至少应该是因为......如果类是设计良好的话,它总是如此)已经是一个实例您需要使用的那个类。即该实例具有您需要访问的状态。
  2. 因此,只是因为你无法访问类的某个实例成员(比如这里的Process()方法)而创建一个全新的类实例总是错误的。

    相反,您需要提供对具有您需要访问权限的状态的已存在实例的访问权限。

    1. 根据您提供的代码的各个部分进行广泛的猜测,我认为ReceiveCallback()方法实际上是在MainWindow类中声明的。如果这个猜测是正确的,那么对代码最明显的修复就是简单地使ReceiveCallback()方法非static。即从方法声明中删除static。完成后,您只需直接致电Process(),而不是先创建MainWindow的新实例。
    2. 现在,您可能(或可能不会)发现提供方法作为原始I / O操作的参数需要修复。同样,由于您没有提供良好的代码示例,因此无法确定是否或如何执行此操作。但我提到它只是为了让你不要简单地放弃这个想法,如果你从声明中删除static后它就不起作用。


      当然,我的猜测可能是错的。在这种情况下,一个选项是提供对MainWindow实例的引用作为I / O操作的状态对象。再说一次,如果没有一个好的代码示例,这究竟是多么有效,但基本的想法是将它作为Socket.BeginReceive()方法的最后一个参数(任何重载)传递,然后从{{{您IAsyncResult.AsyncState方法中的1}}属性。


      注意:以上内容仅用于解决您遇到的特定异常,因为创建新的ReceiveCallback()实例只是保证是错误的做法。由于I / O操作最有可能在UI线程之外完成,因此您仍然遇到与处理该问题相关的问题(例如,需要在访问UI本身的代码上调用MainWindow)。但是一步一步。让我们先解决眼前的问题,然后继续下一步。

      如果以上都不是有用的,那么请修正您的问题,以便它包含一个很好的代码示例,可以提供实际,准确的答案。