2014-01-27 81 views
-1

這是我問的第一個問題,如果我做錯了,請耐心等待。從靜態方法呼叫BackgroundWorker

我正在寫一個軟件從串口a讀取數據,然後用它來更新靜態對象列表的狀態。我收到的每個數據都是一個無線節點的通信,它代表了它的狀態。我解決了閱讀部分,我正在處理搜索和更新部分。

我想使用後臺工作人員搜索列表中的元素,然後更新它,確保用戶一個乾淨和平滑的用戶界面。問題是我通過靜態函數讀取字節,並從該靜態函數中調用backgroundworker來執行任務。我在dotnetperls指南上看到,「RunWorkerAsync可以在代碼中的任何位置調用」,但是當我嘗試從靜態函數調用它時,Visual Studio不讓我這樣做。

任何人都可以幫助我嗎?

[編輯:添加的代碼] 這是我的靜態方法的提取物:

public static void Add(Byte[] received) 
{ 
    List<byte[]> messages = new List<byte[]>(); 
    int lastdollars = 0; 
    byte[] tempmess = new byte[20];  //The message is 20 digits 
    lock (BufferLock) 
    { 
     //I add the last bytes to the buffer (it's a list of bytes) 
     Buffer.AddRange(received); 
     if (Buffer.Count < TOTALMESSAGELENGTH) return; 
     String temp = Encoding.UTF8.GetString(Buffer.ToArray()); 
     //I check the buffer to look for complete messages (there are tokens at the start and at the end 
     for (int i = 0; i <= (temp.Length - TOTALMESSAGELENGTH + 1); i++)   
     { 
      if ((temp.Length > i + TOTALMESSAGELENGTH) && 
       (temp.Substring(i, TOKENLENGTH) == STARTTOKEN) && 
       (temp.Substring((i + TOKENLENGTH + MESSAGELENGTH), TOKENLENGTH) == ENDTOKEN)) 
      { 
       //if I find a message, I put it into the list of messages, I save its position and I continue to look for other messages 
       tempmess = Encoding.UTF8.GetBytes(temp.Substring(i, TOTALMESSAGELENGTH)); 
       messages.Add(tempmess); 
       lastdollars = i; 
       i += TOTALMESSAGELENGTH - 1; 
      } 
     } 
     if (messages.Count == 0) 
      return; 

     //I delete the buffer that I'm using and I need to call the background worker 
     Buffer.RemoveRange(0, (lastdollars + TOTALMESSAGELENGTH)); 
    } 
    worker.RunWorkerAsync(messages); //Error: An object is required for the non-static field, method, or property 'namespace.Form1.worker' 
} 

我嘗試都與限定手動BackgroundWorker的:

private readonly BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += worker_DoWork; 
worker.RunWorkerCompleted += worker_RunWorkerCompleted; 

並通過工具箱添加它,但結果是一樣的。

+0

您能否發佈代碼提取 –

+2

提供代碼片段,以便我們可以看到您將如何調用此方法,然後嘗試幫助您 – simsim

+0

您是否收到這些錯誤之一「...在一個無效的靜態屬性,靜態方法或靜態字段初始值設定項「或」非靜態字段,方法或屬性需要對象引用...「? – samar

回答

0

這與BackgroundWorker或任何特定的類沒有任何關係。這正是C#語言的工作原理。

您無法從靜態函數訪問非靜態成員。靜態函數沒有隱含的this參數,使其針對該類的特定實例運行。您可以運行它,而無需創建任何類的實例。

這個工人

private readonly BackgroundWorker worker = new BackgroundWorker(); 

將爲類的每個實例創建一次。但是你可以調用Add函數而不需要任何實例。

例如,這並不出於同樣的原因工作:

class Adder 
{ 
    public int sum = 0; 

    public static void Add(int x) 
    { 
     sum += x; // can't reference "sum" from static method! 
    } 
} 

... 

Adder.Add(5) 

但這個工程:(!但不同)

class Adder 
{ 
    public int sum = 0; 

    public void Add(int x) // no longer static 
    { 
     sum += x; // this refers to the "sum" variable of this particular instance of Adder 
    } 
} 

... 

var adder = new Adder(); 
adder.Add(5); 

,這也適用:

class Adder 
{ 
    public static int sum = 0; // we made sum static (there is exactly one, instead of a separate sum for each instance) 

    public static void Add(int x) 
    { 
     sum += x; // this refers to the static sum variable 
    } 
} 

... 

Adder.Add(5); 
+0

我知道有靜態變量和方法的含義,但我從來沒有與線程一起工作;因此,我的問題是構造一個能夠處理來自緩衝區讀取器的傳入消息的線程(上面的Add函數)。 – Hamma

1

您無法在靜態方法中訪問實例變量。因此錯誤。嘗試使BackgroundWorker實例保持靜態。像下面這樣。

private readonly static BackgroundWorker worker = new BackgroundWorker(); 

不太確定這是否會破壞您的任何其他代碼。

希望這會有所幫助。